Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit189097d

Browse files
committed
Fix exception safety bug in typcache.c.
If an out-of-memory error was thrown at an unfortunate time,ensure_record_cache_typmod_slot_exists() could leak memory and leavebehind a global state that produced an infinite loop on the next call.Fix by merging RecordCacheArray and RecordIdentifierArray into a singlearray. With only one allocation or re-allocation, there is nointermediate state.Back-patch to all supported releases.Reported-by: "James Pang (chaolpan)" <chaolpan@cisco.com>Reviewed-by: Michael Paquier <michael@paquier.xyz>Discussion:https://postgr.es/m/PH0PR11MB519113E738814BDDA702EDADD6EFA%40PH0PR11MB5191.namprd11.prod.outlook.com
1 parentc570bb4 commit189097d

File tree

2 files changed

+27
-26
lines changed

2 files changed

+27
-26
lines changed

‎src/backend/utils/cache/typcache.c

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -271,10 +271,15 @@ static const dshash_parameters srtr_typmod_table_params = {
271271
/* hashtable for recognizing registered record types */
272272
staticHTAB*RecordCacheHash=NULL;
273273

274-
/* arrays of info about registered record types, indexed by assigned typmod */
275-
staticTupleDesc*RecordCacheArray=NULL;
276-
staticuint64*RecordIdentifierArray=NULL;
277-
staticint32RecordCacheArrayLen=0;/* allocated length of above arrays */
274+
typedefstructRecordCacheArrayEntry
275+
{
276+
uint64id;
277+
TupleDesctupdesc;
278+
}RecordCacheArrayEntry;
279+
280+
/* array of info about registered record types, indexed by assigned typmod */
281+
staticRecordCacheArrayEntry*RecordCacheArray=NULL;
282+
staticint32RecordCacheArrayLen=0;/* allocated length of above array */
278283
staticint32NextRecordTypmod=0;/* number of entries used */
279284

280285
/*
@@ -1583,10 +1588,8 @@ ensure_record_cache_typmod_slot_exists(int32 typmod)
15831588
{
15841589
if (RecordCacheArray==NULL)
15851590
{
1586-
RecordCacheArray= (TupleDesc*)
1587-
MemoryContextAllocZero(CacheMemoryContext,64*sizeof(TupleDesc));
1588-
RecordIdentifierArray= (uint64*)
1589-
MemoryContextAllocZero(CacheMemoryContext,64*sizeof(uint64));
1591+
RecordCacheArray= (RecordCacheArrayEntry*)
1592+
MemoryContextAllocZero(CacheMemoryContext,64*sizeof(RecordCacheArrayEntry));
15901593
RecordCacheArrayLen=64;
15911594
}
15921595

@@ -1597,14 +1600,11 @@ ensure_record_cache_typmod_slot_exists(int32 typmod)
15971600
while (typmod >=newlen)
15981601
newlen *=2;
15991602

1600-
RecordCacheArray= (TupleDesc*)repalloc(RecordCacheArray,
1601-
newlen*sizeof(TupleDesc));
1603+
RecordCacheArray= (RecordCacheArrayEntry*)
1604+
repalloc(RecordCacheArray,
1605+
newlen*sizeof(RecordCacheArrayEntry));
16021606
memset(RecordCacheArray+RecordCacheArrayLen,0,
1603-
(newlen-RecordCacheArrayLen)*sizeof(TupleDesc));
1604-
RecordIdentifierArray= (uint64*)repalloc(RecordIdentifierArray,
1605-
newlen*sizeof(uint64));
1606-
memset(RecordIdentifierArray+RecordCacheArrayLen,0,
1607-
(newlen-RecordCacheArrayLen)*sizeof(uint64));
1607+
(newlen-RecordCacheArrayLen)*sizeof(RecordCacheArrayEntry));
16081608
RecordCacheArrayLen=newlen;
16091609
}
16101610
}
@@ -1642,8 +1642,8 @@ lookup_rowtype_tupdesc_internal(Oid type_id, int32 typmod, bool noError)
16421642
{
16431643
/* It is already in our local cache? */
16441644
if (typmod<RecordCacheArrayLen&&
1645-
RecordCacheArray[typmod]!=NULL)
1646-
returnRecordCacheArray[typmod];
1645+
RecordCacheArray[typmod].tupdesc!=NULL)
1646+
returnRecordCacheArray[typmod].tupdesc;
16471647

16481648
/* Are we attached to a shared record typmod registry? */
16491649
if (CurrentSession->shared_typmod_registry!=NULL)
@@ -1669,19 +1669,19 @@ lookup_rowtype_tupdesc_internal(Oid type_id, int32 typmod, bool noError)
16691669
* Our local array can now point directly to the TupleDesc
16701670
* in shared memory, which is non-reference-counted.
16711671
*/
1672-
RecordCacheArray[typmod]=tupdesc;
1672+
RecordCacheArray[typmod].tupdesc=tupdesc;
16731673
Assert(tupdesc->tdrefcount==-1);
16741674

16751675
/*
16761676
* We don't share tupdesc identifiers across processes, so
16771677
* assign one locally.
16781678
*/
1679-
RecordIdentifierArray[typmod]=++tupledesc_id_counter;
1679+
RecordCacheArray[typmod].id=++tupledesc_id_counter;
16801680

16811681
dshash_release_lock(CurrentSession->shared_typmod_table,
16821682
entry);
16831683

1684-
returnRecordCacheArray[typmod];
1684+
returnRecordCacheArray[typmod].tupdesc;
16851685
}
16861686
}
16871687
}
@@ -1892,10 +1892,10 @@ assign_record_type_typmod(TupleDesc tupDesc)
18921892
ensure_record_cache_typmod_slot_exists(entDesc->tdtypmod);
18931893
}
18941894

1895-
RecordCacheArray[entDesc->tdtypmod]=entDesc;
1895+
RecordCacheArray[entDesc->tdtypmod].tupdesc=entDesc;
18961896

18971897
/* Assign a unique tupdesc identifier, too. */
1898-
RecordIdentifierArray[entDesc->tdtypmod]=++tupledesc_id_counter;
1898+
RecordCacheArray[entDesc->tdtypmod].id=++tupledesc_id_counter;
18991899

19001900
/* Fully initialized; create the hash table entry */
19011901
recentry= (RecordCacheEntry*)hash_search(RecordCacheHash,
@@ -1944,10 +1944,10 @@ assign_record_type_identifier(Oid type_id, int32 typmod)
19441944
* It's a transient record type, so look in our record-type table.
19451945
*/
19461946
if (typmod >=0&&typmod<RecordCacheArrayLen&&
1947-
RecordCacheArray[typmod]!=NULL)
1947+
RecordCacheArray[typmod].tupdesc!=NULL)
19481948
{
1949-
Assert(RecordIdentifierArray[typmod]!=0);
1950-
returnRecordIdentifierArray[typmod];
1949+
Assert(RecordCacheArray[typmod].id!=0);
1950+
returnRecordCacheArray[typmod].id;
19511951
}
19521952

19531953
/* For anonymous or unrecognized record type, generate a new ID */
@@ -2027,7 +2027,7 @@ SharedRecordTypmodRegistryInit(SharedRecordTypmodRegistry *registry,
20272027
TupleDesctupdesc;
20282028
boolfound;
20292029

2030-
tupdesc=RecordCacheArray[typmod];
2030+
tupdesc=RecordCacheArray[typmod].tupdesc;
20312031
if (tupdesc==NULL)
20322032
continue;
20332033

‎src/tools/pgindent/typedefs.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,6 +2019,7 @@ ReadExtraTocPtrType
20192019
ReadFunc
20202020
ReassignOwnedStmt
20212021
RecheckForeignScan_function
2022+
RecordCacheArrayEntry
20222023
RecordCacheEntry
20232024
RecordCompareData
20242025
RecordIOData

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp