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

Commite2452c2

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 parentf7d2511 commite2452c2

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
@@ -272,10 +272,15 @@ static const dshash_parameters srtr_typmod_table_params = {
272272
/* hashtable for recognizing registered record types */
273273
staticHTAB*RecordCacheHash=NULL;
274274

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

281286
/*
@@ -1702,10 +1707,8 @@ ensure_record_cache_typmod_slot_exists(int32 typmod)
17021707
{
17031708
if (RecordCacheArray==NULL)
17041709
{
1705-
RecordCacheArray= (TupleDesc*)
1706-
MemoryContextAllocZero(CacheMemoryContext,64*sizeof(TupleDesc));
1707-
RecordIdentifierArray= (uint64*)
1708-
MemoryContextAllocZero(CacheMemoryContext,64*sizeof(uint64));
1710+
RecordCacheArray= (RecordCacheArrayEntry*)
1711+
MemoryContextAllocZero(CacheMemoryContext,64*sizeof(RecordCacheArrayEntry));
17091712
RecordCacheArrayLen=64;
17101713
}
17111714

@@ -1716,14 +1719,11 @@ ensure_record_cache_typmod_slot_exists(int32 typmod)
17161719
while (typmod >=newlen)
17171720
newlen *=2;
17181721

1719-
RecordCacheArray= (TupleDesc*)repalloc(RecordCacheArray,
1720-
newlen*sizeof(TupleDesc));
1722+
RecordCacheArray= (RecordCacheArrayEntry*)
1723+
repalloc(RecordCacheArray,
1724+
newlen*sizeof(RecordCacheArrayEntry));
17211725
memset(RecordCacheArray+RecordCacheArrayLen,0,
1722-
(newlen-RecordCacheArrayLen)*sizeof(TupleDesc));
1723-
RecordIdentifierArray= (uint64*)repalloc(RecordIdentifierArray,
1724-
newlen*sizeof(uint64));
1725-
memset(RecordIdentifierArray+RecordCacheArrayLen,0,
1726-
(newlen-RecordCacheArrayLen)*sizeof(uint64));
1726+
(newlen-RecordCacheArrayLen)*sizeof(RecordCacheArrayEntry));
17271727
RecordCacheArrayLen=newlen;
17281728
}
17291729
}
@@ -1761,8 +1761,8 @@ lookup_rowtype_tupdesc_internal(Oid type_id, int32 typmod, bool noError)
17611761
{
17621762
/* It is already in our local cache? */
17631763
if (typmod<RecordCacheArrayLen&&
1764-
RecordCacheArray[typmod]!=NULL)
1765-
returnRecordCacheArray[typmod];
1764+
RecordCacheArray[typmod].tupdesc!=NULL)
1765+
returnRecordCacheArray[typmod].tupdesc;
17661766

17671767
/* Are we attached to a shared record typmod registry? */
17681768
if (CurrentSession->shared_typmod_registry!=NULL)
@@ -1788,19 +1788,19 @@ lookup_rowtype_tupdesc_internal(Oid type_id, int32 typmod, bool noError)
17881788
* Our local array can now point directly to the TupleDesc
17891789
* in shared memory, which is non-reference-counted.
17901790
*/
1791-
RecordCacheArray[typmod]=tupdesc;
1791+
RecordCacheArray[typmod].tupdesc=tupdesc;
17921792
Assert(tupdesc->tdrefcount==-1);
17931793

17941794
/*
17951795
* We don't share tupdesc identifiers across processes, so
17961796
* assign one locally.
17971797
*/
1798-
RecordIdentifierArray[typmod]=++tupledesc_id_counter;
1798+
RecordCacheArray[typmod].id=++tupledesc_id_counter;
17991799

18001800
dshash_release_lock(CurrentSession->shared_typmod_table,
18011801
entry);
18021802

1803-
returnRecordCacheArray[typmod];
1803+
returnRecordCacheArray[typmod].tupdesc;
18041804
}
18051805
}
18061806
}
@@ -2010,10 +2010,10 @@ assign_record_type_typmod(TupleDesc tupDesc)
20102010
ensure_record_cache_typmod_slot_exists(entDesc->tdtypmod);
20112011
}
20122012

2013-
RecordCacheArray[entDesc->tdtypmod]=entDesc;
2013+
RecordCacheArray[entDesc->tdtypmod].tupdesc=entDesc;
20142014

20152015
/* Assign a unique tupdesc identifier, too. */
2016-
RecordIdentifierArray[entDesc->tdtypmod]=++tupledesc_id_counter;
2016+
RecordCacheArray[entDesc->tdtypmod].id=++tupledesc_id_counter;
20172017

20182018
/* Fully initialized; create the hash table entry */
20192019
recentry= (RecordCacheEntry*)hash_search(RecordCacheHash,
@@ -2062,10 +2062,10 @@ assign_record_type_identifier(Oid type_id, int32 typmod)
20622062
* It's a transient record type, so look in our record-type table.
20632063
*/
20642064
if (typmod >=0&&typmod<RecordCacheArrayLen&&
2065-
RecordCacheArray[typmod]!=NULL)
2065+
RecordCacheArray[typmod].tupdesc!=NULL)
20662066
{
2067-
Assert(RecordIdentifierArray[typmod]!=0);
2068-
returnRecordIdentifierArray[typmod];
2067+
Assert(RecordCacheArray[typmod].id!=0);
2068+
returnRecordCacheArray[typmod].id;
20692069
}
20702070

20712071
/* For anonymous or unrecognized record type, generate a new ID */
@@ -2145,7 +2145,7 @@ SharedRecordTypmodRegistryInit(SharedRecordTypmodRegistry *registry,
21452145
TupleDesctupdesc;
21462146
boolfound;
21472147

2148-
tupdesc=RecordCacheArray[typmod];
2148+
tupdesc=RecordCacheArray[typmod].tupdesc;
21492149
if (tupdesc==NULL)
21502150
continue;
21512151

‎src/tools/pgindent/typedefs.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2125,6 +2125,7 @@ ReadExtraTocPtrType
21252125
ReadFunc
21262126
ReassignOwnedStmt
21272127
RecheckForeignScan_function
2128+
RecordCacheArrayEntry
21282129
RecordCacheEntry
21292130
RecordCompareData
21302131
RecordIOData

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp