Accessing an invalid pointer in BufferManagerRelation structure

Daniil Davydov <3danissimo@gmail.com>

From: Daniil Davydov <3danissimo@gmail.com>
To: pgsql-hackers@postgresql.org
Date: 2025-01-27T11:38:47Z
Lists: pgsql-hackers

Attachments

Hi,
Postgres allows us to pass BufferManagerRelation structure to
functions in two ways : BMR_REL and BMR_SMGR.
In case we use BMR_REL, the "smgr" field of structure initialized this way :
***
if (bmr.smgr == NULL)
{
    bmr.smgr = RelationGetSmgr(bmr.rel);
    bmr.relpersistence = bmr.rel->rd_rel->relpersistence;
}
***
Thus, we set the "smgr" field only once. But in case of frequent cache
invalidation (for example with debug_discard_caches parameter
enabled),
this pointer may become invalid (because RelationCloseSmgr will be called).
I have not found any places in the current code where this could
happen. But if (just for example) we add acquiring of new lock into
ExtendBufferedRelLocal
or ExtendBufferedRelShared, relation cache will be invalidated (inside
AcceptInvalidationMessages).

I would suggest adding a special macro to access the "smgr" field
(check attached patch for REL_17_STABLE).
What do you think about this?

--
Best regards,
Daniil Davydov

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Make smgr access for a BufferManagerRelation safer in relcache inval

  2. Doc: use "an SQL" consistently rather than "a SQL"