Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1x2R6l-005lis-2s for pgsql-bugs@arkaria.postgresql.org; Fri, 04 Sep 2026 10:25:20 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1x2R6k-0065Dm-1Y for pgsql-bugs@arkaria.postgresql.org; Fri, 04 Sep 2026 10:25:18 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1x2R6j-0065De-2A for pgsql-bugs@lists.postgresql.org; Fri, 04 Sep 2026 10:25:18 +0000 Received: from fout-a2-smtp.messagingengine.com ([103.168.172.145]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1x2R6h-00000003xeo-0vBs for pgsql-bugs@lists.postgresql.org; Fri, 04 Sep 2026 10:25:16 +0000 Received: from phl-compute-02.internal (phl-compute-02.internal [10.202.2.42]) by mailfout.phl.internal (Postfix) with ESMTP id B4AD4EC01B0; Fri, 4 Sep 2026 06:25:13 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-02.internal (MEProxy); Fri, 04 Sep 2026 06:25:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=eisentraut.org; h=cc:cc:content-transfer-encoding:content-type:content-type :date:date:from:from:in-reply-to:in-reply-to:message-id :mime-version:references:reply-to:subject:subject:to:to; s=fm3; t=1788517513; x=1788603913; bh=VX4JLcP03ZZ6gFNhmQSa6bJeJo9oI/Dj 5z9nCPVZfpY=; b=Gd4Uu3Z+k2glMv2qDTJaYJX4xiOeolLJr8/II3wEt5LtayIl 6FUCv+HTkz5hRCeHFjlEYbjrggrI77FR+j61NF0TQcRYOImOIh0BB+KZ/0AnMOJT advv9Eqeq2uXsTwI5A7U537AvwYxPW2SKne30XrYP1DwULLKrfOeUzGtR+RUC8lp 5ko+oeyGGvmOMTJAmif6xlr1/6I/ekt6COhNcm6oM7VbHGoDkyquvCP38NxSkyfJ JMJFpNovbFTxbYLP48SoEq00fDcC/bGXwOFhvCXHGOey8wfn52a/TOvNyKhhA2U8 6q5++YATAukA479y5W2wy9N4GGoTQOh1LDLtuA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1788517513; x= 1788603913; bh=VX4JLcP03ZZ6gFNhmQSa6bJeJo9oI/Dj5z9nCPVZfpY=; b=O 5YpoqdJ1WLly5cTCupotMFWObdNsbOChq52hqgC/VnCwCkE+801NIhHjvBg3rhQ2 gM1oS4iHEyg7u0YI8IqT/qW6NlFjg6a4yrLAxo8pl/LrYFHYAEdz9ZwfHSpN0uKB yHo1q0Eis5kbHPcPN3Ob+D2mISIV61GJIUrKjkmCKUXu+qtOdbvUtZcx/2vC91nN 8w9nPnquQ01j9VoCLmqxX5CnG1+afANo6mYQTvLKNKFFlrP7gq8vVvlvh19fUad6 CQRUDvKPJPzQpT6vUIW0LpJN2jLWhcxSd6VWzKjueP+4dHUtgFg4i99IXuE5uZLY UHS/Kl/GyIDTMPiW1wyYw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTF/Tgvf35WkpHuCi57vQcjoVsszzMDfDMT5Oa9rmBNKkSrLlYa93LhrpCmYU2HBqR BPhCBxV1EffTGJV12vhEu194zhIP7apRlD0mCZHH8SKQKc/GzeeBbm11XGc62l6Py3TSR0 5gHUXt1tHUrzpuZ6PPreuVEMCnggRr+UyV7Ti1T0edEmLFhmwgNfPLVZSvgbfkl0FZZeg9 02Vjdm4xeaK01QkpenjA3OPN2EmLRenUV0374wHW91/fNIU82RQLqofZ/vPY/5UwcLnSAC UXPIIlDqLTYj8VsHr63gEcMJIKAkPvkpYc8zsDZ5AIIqSntuLZxBElObBi0W4ui5uUcAK8 S6NK65IXvcmE/Ear7gu0onLGzHJdgtO61y/6y7rUiCqwKz0UqF6sTuSHjlNSioo9LuqaBE 1uFXgJQW2eDdwCQ1X4FtucTF324Be3UrJcj3ZhAXxGAgiGZ49L2XZNpj3SwyJS1zd8+vfo tjAWBTbutusA94U3grwCFMbMauUpQwGFmAh79Ir3Xi+qdeyPsnSdAK/4wURIMAmcdW2YKF 0FyrFxqZ6n8LRexIZH/pRz4shl2A5xVtjH1pXPx7+jhp2xLfLFy3dzPSbwnxo+emp/CO7U H20DojM1VkN+JhEMrmt/IVHvJel9EoUw8s+Him4wThIL8aBjBwoJAW83JcBA X-ME-Proxy: Feedback-ID: ie0a040ee:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 4 Sep 2026 06:25:12 -0400 (EDT) Message-ID: <479d6c7e-362c-41d8-a263-8d126ecdfd77@eisentraut.org> Date: Fri, 4 Sep 2026 12:25:10 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: BUG #19545: Integer truncation of `GinTuple.keylen` causes out-of-bounds read in parallel GIN index build To: Ewan Young , Heikki Linnakangas Cc: 1217816127@qq.com, pgsql-bugs@lists.postgresql.org References: <19545-0f25b7e47351e8fc@postgresql.org> Content-Language: en-US From: Peter Eisentraut In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 09.07.26 07:16, Ewan Young wrote: >> So we have a hidden assumption that 'data' is Datum-aligned. >> >> >> In _gin_parse_tuple_key() we do this instead: >> >> Datum key; >> ... >> if (a->typbyval) >> { >> memcpy(&key, a->data, a->keylen); >> return key; >> } >> >> That one doesn't require the alignment. I would be inclined to always >> use memcpy() when 'typbyval==true', as above, to not be sensitive to the >> alignment. However, I think we assume that it's aligned for the >> 'typbyval==false' case anyway, as we just do DatumGetPoint(a->data). > Good catch, and this is really surfaced by widening keylen: on master > GinTuple.data lands at offset 16, which is MAXALIGN'd, so that read is > (accidentally) fine; growing the header pushed data off an 8-byte > boundary and exposed the unaligned Datum load. > > Rather than pad data back to MAXALIGN (which grows every GinTuple), I did > what you suggest here -- read the key via the existing > _gin_parse_tuple_key() helper, which already copies byval keys out with > memcpy() and so makes no alignment assumption. That also removes the > duplicated "byval ? deref : pointer" logic, so the key is now read the > same way everywhere; the byref branch is unchanged. > > With the _gin_parse_tuple_key() change the sanitizer is clean -- both at that > 4-aligned offset and with Size (where data happens to be back to > MAXALIGN'd), so the fix doesn't depend on the realignment. In don't think the use of _gin_parse_tuple_key() is sufficient because it only handles the byval side, but the byref side can still fail because of misalignment. Fixing that by copying out byref values as well seems like a more extensive change. The easiest fix (considering backpatching) is that we ensure that GinTuple.data is maxaligned. On 64-bit platforms, we get that by changing keylen to type Size, and that's the correct type anyway relative to the surrounding code, so that seems sound. There is no point in trying for a smaller type (like uint32); that wouldn't buy anything unless you want to consider more extensive surgery in that struct. (I suggest leaving the type of the .typlen field out of this discussion. It would be more correct to use Size for that as well, considering the surrounding code. But then we might realize that .nitems is also of the wrong type, and the types of GinTuple and GinBuffer don't match completely, and so on. Let's leave that for another day.) On 32-bit platforms, it's more complicated because some of them have MAXIMUM_ALIGNOF 4 and some 8. So using a 4-byte Size would make the offset of .data 20 but that wouldn't work on platforms with MAXIMUM_ALIGNOF == 8. In PG19 and later we can force the alignment directly using alignas(MAXIMUM_ALIGNOF) char data[FLEXIBLE_ARRAY_MEMBER]; In PG18, we could either force the alignment using some union trick, or we could brute-force the issue by making keylen of type uint64, possibly combined with a static assertion about the alignment of the .data field somewhere. I would prefer the union trick. That seems consistent with how alignment is forced elsewhere (before the introduction of alignas). (The code is new in PG18, commit 8492feb98f6.)