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 1wUu7k-001Wr5-2M for pgsql-bugs@arkaria.postgresql.org; Wed, 03 Jun 2026 22:31:44 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wUu7j-003k69-1A for pgsql-bugs@arkaria.postgresql.org; Wed, 03 Jun 2026 22:31:43 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wUu7j-003k5y-04 for pgsql-bugs@lists.postgresql.org; Wed, 03 Jun 2026 22:31:43 +0000 Received: from mail-oi1-x232.google.com ([2607:f8b0:4864:20::232]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wUu7g-0000000186W-2jqi for pgsql-bugs@postgresql.org; Wed, 03 Jun 2026 22:31:42 +0000 Received: by mail-oi1-x232.google.com with SMTP id 5614622812f47-486304fa184so26293b6e.1 for ; Wed, 03 Jun 2026 15:31:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1780525898; cv=none; d=google.com; s=arc-20240605; b=atm777WyOi9VGl+Ctz8Jsz7tjhRpT5S6FMeMo87yboxzVwrsI39Awi1z8coM3mQfeW PEF6+glp3SZCvaPAv2vVqdURgg6ZOY4BHjGyRekYo9Y7KjXfpTiQy5RE5E74oNoZ87lm 2YvPA9j7MsLFQOZ248/pOZzz1xnvHci+QoKiHaqTdZFap1V2JS+ikp7/3OttJ1EJz0Is sfz0bykOVcr0boYA1ai/JRZqobiAmLRrJUjpqhrBOSaHmb8gzDHdYUTjiMuFrVccj+z2 89Rm3OtHkU20jX5Bi7SwTcQ7sQuzxPbTrerCoLAal50fa9+xY8o0HeoKK38OTZMcz7f2 G5tw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=izkJcBzuyd+lWQPxBuSg83cNxyVsnPX/J07GZFrjXew=; fh=VZQoudR3iAqjx9kGf9eFpLOSEtEIDJYbkURLh02U0B0=; b=T1tR4pEO5rnn/g6MqFP7dgDdYXZGLikJYSyzPdS5PU86Mufzbw9obzwN6p7fgfpEJF XPOdZOLDKYBkcrVcD0Zn6rnCQUm0YfuJ6VePwI9z82+Fi/QsMhgB1oYvjJScF7SBpgSQ 3sABmS2t1bJWQoOZ2bPH2t3IjKF18sbS7LXCGj4t9eXpj8LN88KahfclVF//xpwRTc4f oh2xwQJ7r0CmxlV7gQ23KvUbaDfPpzw6bMNrxi1m76SV0djvkNmy4g8rGl/BFdaFEelO v1MOCLae/j++tuj+xhYsrlJmss7QHpsR1JrIxnbydtfoqIWHlRrQuRB1jbjnjayTVqmZ 7lYQ==; darn=postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780525898; x=1781130698; darn=postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=izkJcBzuyd+lWQPxBuSg83cNxyVsnPX/J07GZFrjXew=; b=mM37LKTEjUv5R2Roytc45UeJ0N6ng9/VYC3qJQgBvKeP4GrmqHcuA5nhgDWoawiEV3 n4kaSW2XeKka3N07kctM4vVUjt4GwIJ4bzrWkAmelFICZGtRzT69+iXNLrLsy2PTb7VL LUbfrKdW5w69G2R/jr/9WvmHYzcyjvlHL2X/WcTqYO1vzUVvuIxQCsnvK93FBNrrLFqi MayqmBlO7otXcidLJpj++yoJlI2SC/qDqb1UX/k2mkkwN0B7rJnzFPqsNaQOaFXZhVwR uom87CCulh5KPfPdYdDXVzQ9Je1tRLS9Z0ckdwH6kDrAPTWjSfHGfJJV1UqKVZrabrOW xpFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780525898; x=1781130698; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=izkJcBzuyd+lWQPxBuSg83cNxyVsnPX/J07GZFrjXew=; b=fBQvn2AzftjKKxTNJOrDUqx3ROhCC3o4gC4+phggdCQcYs3cOVJ4Nn9l3WXZ+v5umZ PXhAvMlqATcXx172LsqFaKmoSQJ1PItr92k0aeBIu0VJNFUfYI0qZYGFHxBXJvnPCXGj 21ubiapL9W7a7HEouQ8sGva5ayGMB1qQOAh919gd9pIt9UOTiPZ4bd5BXy3ubbvttE2+ nHsdPKr42Vh3UhpXSJv9TER5nFguX3EqtxkloWf5g/wXcd9m5Ag1A3WttbR0L47W/r60 c1JpvYEp6oSgoOc4b6aqznvcGI0ZzAEG8siUzOzvsfzJE63ALRRoJbziDDlIvtiF2Eso 0qHQ== X-Gm-Message-State: AOJu0Yykh2vFezN6guxazpyT+zhSzXT6IV4KtqY0uZpcdAR2UxkKAyyO 4hZSz4l0hq+E9DLCbBwc5ujE7Hdxib3TqeaDNC1N9V8kXCcpWv0AzMMNnIUYOP0uWgGyrX15ZXV Zz07xs3wrfVH0E9fonnLGGxM6jz/XPsY= X-Gm-Gg: Acq92OFXZWY176SmzW8OBnH3ODHcMWjdOFzGB3G9fi56VTs1gUFodNB0cBiQWbDbsiI sKGNMz5Tj2hH3+4WNrwlT/SWYslUVYwwVviD0vUC3aa3qNHbpgAoAC07bGE/rP3pPOnYKo6vlMc BLJzf7Y+EON02cu+DewWnUG9aVayrOf0edfG38FypRQ0kwFOS4+mVeFz0UqBPMneVm/j49VgrbK nCZnEDPHgS3RJyh+885OQ+MleU1Nlhqx/uhtEX0Y52xaIQC6g+rOWt5A6aqrtCHFpI5kcj12s1P Oh2sFco5v56muUK/i2TaHoRGHxG/6DM= X-Received: by 2002:a05:6808:4f60:b0:482:763e:7107 with SMTP id 5614622812f47-4865aafeb0emr3198124b6e.25.1780525898331; Wed, 03 Jun 2026 15:31:38 -0700 (PDT) MIME-Version: 1.0 References: <20260604002256.40f1fd544@smtp.qiye.163.com> In-Reply-To: <20260604002256.40f1fd544@smtp.qiye.163.com> From: surya poondla Date: Wed, 3 Jun 2026 15:31:27 -0700 X-Gm-Features: AVHnY4LsvSzVWDg9HwgBT2TFwMlfkkliR-5sziB_nBOPs958jyICjr6Hwp2FVwA Message-ID: Subject: Re: Fw: Re: heap_force_common in contrib/pg_surgery/heap_surgery.c has an off by one stack buffer overflow To: "violin0613@tju.edu.cn" Cc: pgsql-bugs@postgresql.org Content-Type: multipart/mixed; boundary="000000000000af21be065360fd0f" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000af21be065360fd0f Content-Type: multipart/alternative; boundary="000000000000af21bc065360fd0d" --000000000000af21bc065360fd0d Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi =E7=8E=8B=E8=B7=83=E6=9E=97, Thank you for reporting the issue, I am able to reproduce it on master. The include_this_tid[] array is sized MaxHeapTuplesPerPage but indexed using 1-based OffsetNumber, so the largest legal offset (MaxHeapTuplesPerPage itself) lands one slot past the end. psql (19beta1) Type "help" for help. postgres=3D# CREATE EXTENSION IF NOT EXISTS pg_surgery; CREATE EXTENSION postgres=3D# CREATE TABLE vuln_005_t(); CREATE TABLE postgres=3D# INSERT INTO vuln_005_t SELECT FROM generate_series(1, 291); INSERT 0 291 postgres=3D# SELECT heap_force_freeze('vuln_005_t'::regclass, ARRAY['(0, 291)']::tid[]); server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request. The connection to the server was lost. Attempting reset: Failed. The connection to the server was lost. Attempting reset: Failed. !?> q -?> q -?> !?> quit Proposed patch attached. It does two things: 1. Resize include_this_tid[] to MaxHeapTuplesPerPage + 1 so every legal 1-based offset has a slot. This removes the structural off-by-one 2. Extend the per-TID input check to also reject offno > MaxHeapTuplesPerPa= ge, so a corrupted page whose pd_lower lets max offset exceed the structural maximum cannot reach the array either. With the patch I no longer see the crash postgres=3D# DROP TABLE IF EXISTS vuln_005_t; DROP TABLE postgres=3D# DROP EXTENSION IF EXISTS pg_surgery; DROP EXTENSION postgres=3D# postgres=3D# CREATE EXTENSION pg_surgery; CREATE EXTENSION postgres=3D# CREATE TABLE vuln_005_t(); CREATE TABLE postgres=3D# INSERT INTO vuln_005_t SELECT FROM generate_series(1, 291); INSERT 0 291 postgres=3D# SELECT count(*) FROM vuln_005_t; count ------- 291 (1 row) postgres=3D# SELECT heap_force_freeze('vuln_005_t'::regclass, ARRAY['(0, 291)']::tid[]); heap_force_freeze ------------------- (1 row) Regards, Surya Poondla --000000000000af21bc065360fd0d Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi =E7=8E=8B=E8=B7=83=E6=9E=97,

Thank you for repor= ting the issue, I am able to reproduce it on master.
The=C2=A0include_th= is_tid[] array is sized=C2=A0MaxHeapTuplesPerPage but indexed using 1-based= =C2=A0OffsetNumber,=C2=A0
so the largest legal offset (MaxHeapTuplesPer= Page itself) lands one slot past the end.

psql (19beta1)

Type "help" for help.


postgres=3D# CREATE EXTENSION IF NOT EXISTS pg_surgery;

CREATE EXTENSION

postgres=3D# CREATE TABLE vuln_005_t();

CREATE TABLE

postgres=3D# INSERT INTO vuln_005_t SELECT FROM generate_= series(1, 291);

INSERT 0 291

postgres=3D# SELECT heap_force_freeze('vuln_005_t'= ;::regclass, ARRAY['(0, 291)']::tid[]);

server closed the connection unexpectedly

=C2=A0 =C2=A0= =C2=A0 =C2=A0 This probably means the server terminated abnormally<= /p>

=C2=A0 =C2=A0= =C2=A0 =C2=A0 before or while processing the request.

The connection to the server was lost. Attempting reset: = Failed.

The connection to the server was lost. Attempting reset: = Failed.

!?> q

-?> q

-?>=C2=A0<= /span>

!?> quit

Proposed patch attached.=C2=A0 It does= two things:
1.=C2=A0Resize include_this_tid[] to MaxHeapTuplesPerPage + 1 s= o every=C2=A0legal 1-based offset has a slot.=C2=A0 This removes the str= uctural off-by-one
2.=C2=A0
Extend the per-TID input check to also = reject offno >=C2=A0MaxHeapTuplesPerPage, so a corrupted page whose p= d_lower lets max offset exceed the structural maximum cannot reach the arra= y either.

With the patch I no longer see the crash

postgres=3D# =C2=A0 DROP TABLE IF EXISTS vuln_005_t;

DRO= P TABLE

postgres=3D# =C2=A0 DROP EXTENSION IF EXISTS pg_surgery;

DROP EXTENSION

postgres=3D#=C2=A0

postgres=3D# = CREATE EXTENSION pg_surgery;

CREATE EXTENSION

postgres=3D# CREATE TABLE vuln_005_t();

C= REATE TABLE

postgres=3D# INSERT INTO vuln_005_t SELECT= FROM generate_series(1, 291);

INSERT 0 291

postgres=3D# SELECT count(*) FROM vuln_005_t;

=C2=A0count=C2=A0

------= -

=C2=A0= =C2=A0 291

(1 row)


postgres=3D# SELECT heap_force_freeze(&#= 39;vuln_005_t'::regclass, ARRAY['(0, 291)']::tid[]);

=C2=A0heap_fo= rce_freeze=C2=A0

-------------------

=C2=A0

(1 row)

Regards,
Surya Poondla

--000000000000af21bc065360fd0d-- --000000000000af21be065360fd0f Content-Type: application/octet-stream; name="0001-Fix-off-by-one-stack-buffer-overflow-in-pg_surgery.patch" Content-Disposition: attachment; filename="0001-Fix-off-by-one-stack-buffer-overflow-in-pg_surgery.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mpyn3wti0 RnJvbSBiNGM2MmQ0ZDMyNjgzMzQxYjNhMzQ0OTM2ZThhYzhhZDk1OGQ5ZjdiIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBzcG9vbmRsYSA8c19wb29uZGxhQGFwcGxlLmNvbT4KRGF0ZTog V2VkLCAzIEp1biAyMDI2IDE1OjE3OjAwIC0wNzAwClN1YmplY3Q6IFtQQVRDSF0gRml4IG9mZi1i eS1vbmUgc3RhY2sgYnVmZmVyIG92ZXJmbG93IGluIHBnX3N1cmdlcnkgSXNzdWU6CiBoZWFwX2Zv cmNlX2NvbW1vbigpIGRlY2xhcmVkIGluY2x1ZGVfdGhpc190aWRbXSB3aXRoIE1heEhlYXBUdXBs ZXNQZXJQYWdlCiBzbG90cyBhbmQgaW5kZXhlZCBpdCBkaXJlY3RseSB3aXRoIGEgMS1iYXNlZCBP ZmZzZXROdW1iZXIsIHNvIGFuIGlucHV0IFRJRAogd2hvc2Ugb2Zmc2V0IG51bWJlciBlcXVhbHMg TWF4SGVhcFR1cGxlc1BlclBhZ2Ugd3JvdGUgb25lIGJ5dGUgcGFzdCB0aGUgZW5kCiBvZiB0aGUg c3RhY2sgYXJyYXkgYW5kIHRoaXMgd291bG9kIGNhdXNlIGEgc2VnIGZhdWx0IGFuZCBjcmFzaCBw b3N0Z3JlcwoKRml4OgpVcGRhdGVkIHRoZSBzaXplIG9mIGluY2x1ZGVfdGhpc190aWRbXSBhcyBN YXhIZWFwVHVwbGVzUGVyUGFnZSArIDEgc28gZXZlcnkgbGVnYWwKMS1iYXNlZCBvZmZzZXQgaGFz IGEgc2xvdCwgYW5kIHJlamVjdCBvZmZubyA+IE1heEhlYXBUdXBsZXNQZXJQYWdlIGluCnRoZSBw ZXItVElEIHZhbGlkYXRpb24gc28gYSBjb3JydXB0ZWQgcGFnZSBoZWFkZXIgdGhhdCByZXBvcnRz IGFuCmltcG9zc2libHkgbGFyZ2UgbWF4b2Zmc2V0IGNhbm5vdCByZWFjaCB0aGUgYXJyYXkgZWl0 aGVyLgotLS0KIGNvbnRyaWIvcGdfc3VyZ2VyeS9oZWFwX3N1cmdlcnkuYyB8IDkgKysrKysrLS0t CiAxIGZpbGUgY2hhbmdlZCwgNiBpbnNlcnRpb25zKCspLCAzIGRlbGV0aW9ucygtKQoKZGlmZiAt LWdpdCBhL2NvbnRyaWIvcGdfc3VyZ2VyeS9oZWFwX3N1cmdlcnkuYyBiL2NvbnRyaWIvcGdfc3Vy Z2VyeS9oZWFwX3N1cmdlcnkuYwppbmRleCBhZTRlN2MwMTM2Yy4uMTkxNjkxMzE4MTUgMTAwNjQ0 Ci0tLSBhL2NvbnRyaWIvcGdfc3VyZ2VyeS9oZWFwX3N1cmdlcnkuYworKysgYi9jb250cmliL3Bn X3N1cmdlcnkvaGVhcF9zdXJnZXJ5LmMKQEAgLTkyLDcgKzkyLDggQEAgaGVhcF9mb3JjZV9jb21t b24oRnVuY3Rpb25DYWxsSW5mbyBmY2luZm8sIEhlYXBUdXBsZUZvcmNlT3B0aW9uIGhlYXBfZm9y Y2Vfb3B0KQogCVJlbGF0aW9uCXJlbDsKIAlPZmZzZXROdW1iZXIgY3Vycl9zdGFydF9wdHIsCiAJ CQkJbmV4dF9zdGFydF9wdHI7Ci0JYm9vbAkJaW5jbHVkZV90aGlzX3RpZFtNYXhIZWFwVHVwbGVz UGVyUGFnZV07CisJLyogU2l6ZWQgKzEgYmVjYXVzZSBPZmZzZXROdW1iZXJzIGFyZSAxLWJhc2Vk IGFuZCBjYW4gcmVhY2ggTWF4SGVhcFR1cGxlc1BlclBhZ2UuICovCisJYm9vbAkJaW5jbHVkZV90 aGlzX3RpZFtNYXhIZWFwVHVwbGVzUGVyUGFnZSArIDFdOwogCiAJaWYgKFJlY292ZXJ5SW5Qcm9n cmVzcygpKQogCQllcmVwb3J0KEVSUk9SLApAQCAtMTkzLDcgKzE5NCw5IEBAIGhlYXBfZm9yY2Vf Y29tbW9uKEZ1bmN0aW9uQ2FsbEluZm8gZmNpbmZvLCBIZWFwVHVwbGVGb3JjZU9wdGlvbiBoZWFw X2ZvcmNlX29wdCkKIAkJCUl0ZW1JZAkJaXRlbWlkOwogCiAJCQkvKiBDaGVjayB3aGV0aGVyIHRo ZSBvZmZzZXQgbnVtYmVyIGlzIHZhbGlkLiAqLwotCQkJaWYgKG9mZm5vID09IEludmFsaWRPZmZz ZXROdW1iZXIgfHwgb2Zmbm8gPiBtYXhvZmZzZXQpCisJCQlpZiAob2Zmbm8gPT0gSW52YWxpZE9m ZnNldE51bWJlciB8fAorCQkJCW9mZm5vID4gbWF4b2Zmc2V0IHx8CisJCQkJb2Zmbm8gPiBNYXhI ZWFwVHVwbGVzUGVyUGFnZSkKIAkJCXsKIAkJCQllcmVwb3J0KE5PVElDRSwKIAkJCQkJCWVycm1z Zygic2tpcHBpbmcgdGlkICgldSwgJXUpIGZvciByZWxhdGlvbiBcIiVzXCIgYmVjYXVzZSB0aGUg aXRlbSBudW1iZXIgaXMgb3V0IG9mIHJhbmdlIiwKQEAgLTIyOCw3ICsyMzEsNyBAQCBoZWFwX2Zv cmNlX2NvbW1vbihGdW5jdGlvbkNhbGxJbmZvIGZjaW5mbywgSGVhcFR1cGxlRm9yY2VPcHRpb24g aGVhcF9mb3JjZV9vcHQpCiAJCQl9CiAKIAkJCS8qIE1hcmsgaXQgZm9yIHByb2Nlc3NpbmcuICov Ci0JCQlBc3NlcnQob2Zmbm8gPCBNYXhIZWFwVHVwbGVzUGVyUGFnZSk7CisJCQlBc3NlcnQob2Zm bm8gPD0gTWF4SGVhcFR1cGxlc1BlclBhZ2UpOwogCQkJaW5jbHVkZV90aGlzX3RpZFtvZmZub10g PSB0cnVlOwogCQl9CiAKLS0gCjIuMzkuNSAoQXBwbGUgR2l0LTE1NCkKCg== --000000000000af21be065360fd0f--