Skip to content

Commit 0f714c6

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 d8f2858 commit 0f714c6

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
@@ -414,6 +414,9 @@ CreateFakeRelcacheEntry(RelFileNode rnode)
414414
void
415415
FreeFakeRelcacheEntry(Relation fakerel)
416416
{
417+
/* make sure the fakerel is not referenced by the SmgrRelation anymore */
418+
if (fakerel->rd_smgr != NULL)
419+
smgrclearowner(&fakerel->rd_smgr, fakerel->rd_smgr);
417420
pfree(fakerel);
418421
}
419422

src/backend/storage/smgr/smgr.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,24 @@ smgrsetowner(SMgrRelation *owner, SMgrRelation reln)
197197
*owner = reln;
198198
}
199199

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

src/include/storage/smgr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ extern void smgrinit(void);
7373
extern SMgrRelation smgropen(RelFileNode rnode);
7474
extern bool smgrexists(SMgrRelation reln, ForkNumber forknum);
7575
extern void smgrsetowner(SMgrRelation *owner, SMgrRelation reln);
76+
extern void smgrclearowner(SMgrRelation *owner, SMgrRelation reln);
7677
extern void smgrclose(SMgrRelation reln);
7778
extern void smgrcloseall(void);
7879
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