public inbox for [email protected]  
help / color / mirror / Atom feed
From: Heikki Linnakangas <[email protected]>
To: Ewan Young <[email protected]>
To: [email protected]
To: [email protected]
Subject: Re: BUG #19545: Integer truncation of `GinTuple.keylen` causes out-of-bounds read in parallel GIN index build
Date: Wed, 8 Jul 2026 10:52:50 +0300
Message-ID: <[email protected]> (raw)
In-Reply-To: <CAON2xHMXYLwkq4UaNbUtmaw1ZKne6OqdyyiACFQUbCj+XRBvQQ@mail.gmail.com>
References: <[email protected]>
	<CAON2xHMXYLwkq4UaNbUtmaw1ZKne6OqdyyiACFQUbCj+XRBvQQ@mail.gmail.com>

On 08/07/2026 09:27, Ewan Young wrote:
> Hi Yuelin,
> 
> Thanks for the very precise report -- I reproduced it on master and your
> analysis is exactly right. _gin_build_tuple() builds the whole GinTuple
> (palloc size, key memcpy, TID-list offset) from the int keylen, but the
> stored GinTuple.keylen is uint16, so a key wider than 65535 bytes has its
> stored length truncated. On read-back GinTupleGetFirst() and
> _gin_parse_tuple_items() recompute the posting-list offset from the
> truncated value, and ginPostingListDecodeAllSegments() then walks the key
> bytes, aborting (or reading past the allocation on non-assert builds)
> exactly as you saw. It's parallel-only because only the parallel path
> serializes a GinTuple.
> 
> I went with your fix A -- widening keylen to uint32 (attached). It's the
> minimal root-cause fix: the stored length now matches the length the rest
> of the function already uses.

Ugh, the datatypes used for keylen are all over the place. In GinTuple 
struct it was 'uint16', in GinBuffer it's Size, and in the 
_gin_build_tuple() function's local variable it's 'int'. Would be good 
to make them consistent.

> I preferred it over an explicit ereport at
> UINT16_MAX, since 65535 isn't a meaningful GIN limit -- the entry-tree item
> limit is much smaller and is applied to the (compressed) tuple by
> GinFormTuple() -- so rejecting there would be an arbitrary cutoff.

Hmm, we don't compress the key data though, so a tuple with a key larger 
than 65535 will inevitably fail in GinFormTuple(), right? I agree it 
would be a little arbitrary to cut off at 65535, but then again, it 
seems a little silly to continue when we know it's just going to fail 
later on. I think it would make sense to check if keylen > 
GinMaxItemSize. It might still fail later in GinFormTuple(), because the 
index tuple headers take some space, but still.

- Heikki






view thread (9+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected], [email protected]
  Subject: Re: BUG #19545: Integer truncation of `GinTuple.keylen` causes out-of-bounds read in parallel GIN index build
  In-Reply-To: <[email protected]>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox