Skip to content

Commit d411d6e

Browse files
committed
Fix dangling smgr_owner pointer when a fake relcache entry is freed.
A fake relcache entry can "own" a SmgrRelation object, like a regular relcache entry. But when it was free'd, the owner field in SmgrRelation was not cleared, so it was left pointing to free'd memory. Amazingly this apparently hasn't caused crashes in practice, or we would've heard about it earlier. Andres found this with Valgrind. Report and fix by Andres Freund, with minor modifications by me. Backpatch to all supported versions.
1 parent ff9d757 commit d411d6e

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

src/backend/access/transam/xlogutils.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,9 @@ CreateFakeRelcacheEntry(RelFileNode rnode)
413413
void
414414
FreeFakeRelcacheEntry(Relation fakerel)
415415
{
416+
/* make sure the fakerel is not referenced by the SmgrRelation anymore */
417+
if (fakerel->rd_smgr != NULL)
418+
smgrclearowner(&fakerel->rd_smgr, fakerel->rd_smgr);
416419
pfree(fakerel);
417420
}
418421

src/backend/storage/smgr/smgr.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,24 @@ smgrsetowner(SMgrRelation *owner, SMgrRelation reln)
193193
*owner = reln;
194194
}
195195

196+
/*
197+
* smgrclearowner() -- Remove long-lived reference to an SMgrRelation object
198+
* if one exists
199+
*/
200+
void
201+
smgrclearowner(SMgrRelation *owner, SMgrRelation reln)
202+
{
203+
/* Do nothing if the SMgrRelation object is not owned by the owner */
204+
if (reln->smgr_owner != owner)
205+
return;
206+
207+
/* unset the owner's reference */
208+
*owner = NULL;
209+
210+
/* unset our reference to the owner */
211+
reln->smgr_owner = NULL;
212+
}
213+
196214
/*
197215
* smgrexists() -- Does the underlying file for a fork exist?
198216
*/

src/include/storage/smgr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ extern void smgrinit(void);
6262
extern SMgrRelation smgropen(RelFileNode rnode);
6363
extern bool smgrexists(SMgrRelation reln, ForkNumber forknum);
6464
extern void smgrsetowner(SMgrRelation *owner, SMgrRelation reln);
65+
extern void smgrclearowner(SMgrRelation *owner, SMgrRelation reln);
6566
extern void smgrclose(SMgrRelation reln);
6667
extern void smgrcloseall(void);
6768
extern void smgrclosenode(RelFileNode rnode);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy