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

Commita26cc03

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 parent75b4f93 commita26cc03

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

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

282287
/*
@@ -1703,25 +1708,20 @@ ensure_record_cache_typmod_slot_exists(int32 typmod)
17031708
{
17041709
if (RecordCacheArray==NULL)
17051710
{
1706-
RecordCacheArray= (TupleDesc*)
1707-
MemoryContextAllocZero(CacheMemoryContext,64*sizeof(TupleDesc));
1708-
RecordIdentifierArray= (uint64*)
1709-
MemoryContextAllocZero(CacheMemoryContext,64*sizeof(uint64));
1711+
RecordCacheArray= (RecordCacheArrayEntry*)
1712+
MemoryContextAllocZero(CacheMemoryContext,64*sizeof(RecordCacheArrayEntry));
17101713
RecordCacheArrayLen=64;
17111714
}
17121715

17131716
if (typmod >=RecordCacheArrayLen)
17141717
{
17151718
int32newlen=pg_nextpower2_32(typmod+1);
17161719

1717-
RecordCacheArray= (TupleDesc*)repalloc(RecordCacheArray,
1718-
newlen*sizeof(TupleDesc));
1720+
RecordCacheArray= (RecordCacheArrayEntry*)
1721+
repalloc(RecordCacheArray,
1722+
newlen*sizeof(RecordCacheArrayEntry));
17191723
memset(RecordCacheArray+RecordCacheArrayLen,0,
1720-
(newlen-RecordCacheArrayLen)*sizeof(TupleDesc));
1721-
RecordIdentifierArray= (uint64*)repalloc(RecordIdentifierArray,
1722-
newlen*sizeof(uint64));
1723-
memset(RecordIdentifierArray+RecordCacheArrayLen,0,
1724-
(newlen-RecordCacheArrayLen)*sizeof(uint64));
1724+
(newlen-RecordCacheArrayLen)*sizeof(RecordCacheArrayEntry));
17251725
RecordCacheArrayLen=newlen;
17261726
}
17271727
}
@@ -1759,8 +1759,8 @@ lookup_rowtype_tupdesc_internal(Oid type_id, int32 typmod, bool noError)
17591759
{
17601760
/* It is already in our local cache? */
17611761
if (typmod<RecordCacheArrayLen&&
1762-
RecordCacheArray[typmod]!=NULL)
1763-
returnRecordCacheArray[typmod];
1762+
RecordCacheArray[typmod].tupdesc!=NULL)
1763+
returnRecordCacheArray[typmod].tupdesc;
17641764

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

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

17981798
dshash_release_lock(CurrentSession->shared_typmod_table,
17991799
entry);
18001800

1801-
returnRecordCacheArray[typmod];
1801+
returnRecordCacheArray[typmod].tupdesc;
18021802
}
18031803
}
18041804
}
@@ -2011,10 +2011,10 @@ assign_record_type_typmod(TupleDesc tupDesc)
20112011
ensure_record_cache_typmod_slot_exists(entDesc->tdtypmod);
20122012
}
20132013

2014-
RecordCacheArray[entDesc->tdtypmod]=entDesc;
2014+
RecordCacheArray[entDesc->tdtypmod].tupdesc=entDesc;
20152015

20162016
/* Assign a unique tupdesc identifier, too. */
2017-
RecordIdentifierArray[entDesc->tdtypmod]=++tupledesc_id_counter;
2017+
RecordCacheArray[entDesc->tdtypmod].id=++tupledesc_id_counter;
20182018

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

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

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

‎src/tools/pgindent/typedefs.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2218,6 +2218,7 @@ ReadLocalXLogPageNoWaitPrivate
22182218
ReadReplicationSlotCmd
22192219
ReassignOwnedStmt
22202220
RecheckForeignScan_function
2221+
RecordCacheArrayEntry
22212222
RecordCacheEntry
22222223
RecordCompareData
22232224
RecordIOData

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp