Skip to content

SHMEM_ATTACH_UNKNOWN_SIZE reaches InitShmemIndexEntry() - #425

Open
pg-hub-mirror[bot] wants to merge 1 commit into
masterfrom
pg-hub/mirror-patch-217bb951d4aa811a
Open

pg-hub-mirror[bot] wants to merge 1 commit into
masterfrom
pg-hub/mirror-patch-217bb951d4aa811a

Conversation

@pg-hub-mirror

@pg-hub-mirror pg-hub-mirror Bot commented Sep 18, 2026

Copy link
Copy Markdown

Read-only mirror. Reply and review on pgsql-hackers; activity here is not sent upstream.

  • Original author: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
  • Mailing list: pgsql-hackers
  • Message-ID: CAExHW5u_fTsOAS85kG981Vu6eR1GV-344rup6zYew7xMjEDREw@mail.gmail.com
  • Original email

Patch files:


Hi All, Heikki,
SHMEM_ATTACH_UNKNOWN_SIZE can be passed as argument to
ShmemRequestStruct() when the caller wants to attach to an existing
shared memory structure, whose size it does not know, after the
startup. If the shared memory structure it wants to attach to does not
exist, the request should fail. But instead
ProcessShmemRequestsAfterStartup() ended up creating the structure
with size = -1. InitShmemIndexEntry() did not catch it and created a
ShmemIndexEntry with size = SIZE_MAX since size is an unsigned
integer. ShmemAllocRaw() did not catch the overflow in address
arithmetic and ended up allocating the new structure overlapping the
earlier structure which can potentially cause memory corruption.
Attached patch fixes ProcessShmemRequestsAfterStartup() throw an error
in this case, adds an Assert() in InitShmemIndexEntry() to make sure
that a request with unknown size never reaches it, makes
ShmemAllocRaw() check for overflow, and documents use of
SHMEM_ATTACH_UNKNOWN_SIZE.
I found this problem when working on resizable shared structures where
the size of the structure may have changed from its initial size and
hence may not be known. It's good to defend our shared memory
structures from a bug in extension code.

Best Wishes,
Ashutosh Bapat

SHMEM_ATTACH_UNKNOWN_SIZE can be passed as argument to
ShmemRequestStruct() when the caller wants to attach to an existing
shared memory structure, whose size it does not know, after the startup.
If the shared memory structure it wants to attach to does not exist, the
request should fail. But instead ProcessShmemRequestsAfterStartup()
ended up creating the structure with size = -1. InitShmemIndexEntry()
did not catch it and created a ShmemIndexEntry with size = SIZE_MAX
since size is an unsigned integer. ShmemAllocRaw() did not catch the
overflow in size arithmetic and ended up allocating the new structure
overlapping the earlier structure which can potentially cause memory
corruption.

Fix this by making ProcessShmemRequestsAfterStartup() reject the
requests with size = SHMEM_ATTACH_UNKNOWN_SIZE when the structure with
the requested name does not exist.  Add an Assert() in
InitShmemIndexEntry() to make sure that a request with unknown size
never reaches it. Also make ShmemAllocRaw() check for overflow in its
size arithmetic, as defense-in-depth against a similar mistake silently
corrupting memory in the future. Also document use of
SHMEM_ATTACH_UNKNOWN_SIZE.

Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Discussion: TBD
@pg-hub-mirror pg-hub-mirror Bot added area:storage Storage, access methods, buffers, or I/O source:pgsql-hackers Mirrored from pgsql-hackers type:patch Mail thread contains a PostgreSQL patch labels Sep 18, 2026
@pg-hub-mirror pg-hub-mirror Bot locked and limited conversation to collaborators Sep 18, 2026
@pg-hub-mirror pg-hub-mirror Bot unlocked this conversation Sep 18, 2026
@pg-hub-mirror

pg-hub-mirror Bot commented Sep 18, 2026

Copy link
Copy Markdown
Author

Heikki Linnakangas <hlinnaka(at)iki(dot)fi> via pgsql-hackers · original email

On 18/09/2026 10:00, Ashutosh Bapat wrote:

SHMEM_ATTACH_UNKNOWN_SIZE can be passed as argument to
ShmemRequestStruct() when the caller wants to attach to an existing
shared memory structure, whose size it does not know, after the
startup. If the shared memory structure it wants to attach to does not
exist, the request should fail. But instead
ProcessShmemRequestsAfterStartup() ended up creating the structure
with size = -1. InitShmemIndexEntry() did not catch it and created a
ShmemIndexEntry with size = SIZE_MAX since size is an unsigned
integer. ShmemAllocRaw() did not catch the overflow in address
arithmetic and ended up allocating the new structure overlapping the
earlier structure which can potentially cause memory corruption.

Attached patch fixes ProcessShmemRequestsAfterStartup() throw an error
in this case, adds an Assert() in InitShmemIndexEntry() to make sure
that a request with unknown size never reaches it, makes
ShmemAllocRaw() check for overflow, and documents use of
SHMEM_ATTACH_UNKNOWN_SIZE.

I found this problem when working on resizable shared structures where
the size of the structure may have changed from its initial size and
hence may not be known. It's good to defend our shared memory
structures from a bug in extension code.
Committed with minor cosmetic changes, thanks!

  • Heikki

@pg-hub-mirror pg-hub-mirror Bot locked and limited conversation to collaborators Sep 18, 2026
@pg-hub-mirror pg-hub-mirror Bot added cf:pg20-2 PostgreSQL CommitFest status:committed CommitFest: Committed labels Sep 19, 2026
@pg-hub-mirror pg-hub-mirror Bot added this to the PG20-2 milestone Sep 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area:storage Storage, access methods, buffers, or I/O cf:pg20-2 PostgreSQL CommitFest source:pgsql-hackers Mirrored from pgsql-hackers status:committed CommitFest: Committed type:patch Mail thread contains a PostgreSQL patch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant