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 1waDer-001c9q-2v for pgsql-bugs@arkaria.postgresql.org; Thu, 18 Jun 2026 14:23:54 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1waDeq-00BnEs-1e for pgsql-bugs@arkaria.postgresql.org; Thu, 18 Jun 2026 14:23:52 +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 1waDeq-00BnEk-0O for pgsql-bugs@lists.postgresql.org; Thu, 18 Jun 2026 14:23:52 +0000 Received: from mail-yw1-x1133.google.com ([2607:f8b0:4864:20::1133]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1waDeo-00000000z1B-1MkU for pgsql-bugs@lists.postgresql.org; Thu, 18 Jun 2026 14:23:50 +0000 Received: by mail-yw1-x1133.google.com with SMTP id 00721157ae682-7e86d46b02dso13032627b3.3 for ; Thu, 18 Jun 2026 07:23:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1781792629; cv=none; d=google.com; s=arc-20240605; b=RqQQAzYCpbZ7kpNwgiMd3cm714qJOjsmTa34vPCBsI49euCL9q8icNxTGHKJNlZwvN y1kVjcImxU+WIfvntESiPPqr0GMPwS4k5fm3bJfJ73xmmcOyCMzfFfd42eE0NX56kFTQ 8o89fGUgvrlzkOL/xdBwVEUmRT32EQozZfPn4AmvvQig0PN/35gSFOtELrKhA+RO9B7W Atw1Tn24zyy7dom9n81T+1nnQLZ9TCznqALdIo9ieaBgMEhHx4g7nEcaiz07/Xqnca4L HNBHD6c7qnak35RQVfGtt6UFGKYF8nn+AxTsNyiYi/C3ZHVNZPRMqsYJBJC2dV3198Zn iVsg== 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=s1968hXp6Zart+h1Ii4BhEkQDUvZ9fNuDmWxBJirAao=; fh=khmKU+GndRySK6BbEyVcLV2O9zluYTmotLo8NLAUKsA=; b=KyBgqD9Zkksz60jEfNFtJRV1hm2T0sNjkRhOo3SzRl0ijw8miqAu40Hlus8JTlvXpj AsSrS3BYIj3zgWTpZe3ciWn2oI5azhspAK/u0OwGGIzFvPfelDaOJIF78gEiP7VCC00t J20D3PecN5ijAmc8K1ZAIPEVbKTZcpTPy9vCiAT9eeGHgcM3wcAWWZ+g6R7qCTHygG0/ d1a7Bi1nzf68ddS3NqK1JhIL5Pd5DcpnmDpiqQjFkt67BtE0RC5i62BcvdVHZ6NL9NE3 qhq5QzLnbWHfCiMBhW7aurFYIKzlaCUQ8RE6uipQgjkk4DiogZQlJ64QCF93iAX47ao+ ZqqQ==; darn=lists.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=1781792629; x=1782397429; darn=lists.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=s1968hXp6Zart+h1Ii4BhEkQDUvZ9fNuDmWxBJirAao=; b=ZPCHjTutOGnZGOplU3lsQnWaiLOYTjeodiUFlAtwtVS8f/NFaeetVfqiEBr8fFFsxH czwZYlEGegps5BpQNlGthnX10vIAWvApH6BoWyQ5b7WAAKdyiDtq4GicQ2aExkmOLR9u gklNli5V2Q2lxWk9C2FngMNGOqPpYDrILD3QPypVvVUlEUoUVW4vd0nhnI1WV1KJ3UaX jD6Sn2ggJgqDpYJsw59nrl26BzAyMggU5qAYXexDisnjkyqgPuQyahRvLeoRDB5mkIGr j2SJyB/M+6u5rllvj5tCOuq1/aqi7BS6Pl96fWeTbbgQyWjqPcIOwnBWzGxc6PqMoXNL 9bkw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781792629; x=1782397429; 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=s1968hXp6Zart+h1Ii4BhEkQDUvZ9fNuDmWxBJirAao=; b=GBVEX34YLe6pvOIMwl/aEsKQSXDUvFLrSF5vGtkGh0tJqYYd4uiFK7litklrcqqDVR qMwpVSPN9s18uXWB/tUOcPZt1KWMpHarZ8Rq7F+vPzyKwxiL0surd3SIb+U4Xdzm7VEN FWB6E0NRlj870BQjWGkSktSRafvBoEwT3sGqi2svGB9HCQbturraw0PFTqfSJEOu9HcQ b1aJh8bW73+xvtrrpLgskTPLfdKdCN24nTuqKvgZVSdHgJTavo7zOZQw/WjenARbdSSX EpjqpJCgxEaBVqWqWK3UCwW1kYkLuEt7E46eogtl7LRHw4xyCr9iHkvQhGTjWkt1RdX9 EIhQ== X-Gm-Message-State: AOJu0YwDds2PJoREasYc5mHZ3O3x8K1Gynd9+Us4SEatXa9MXP+OR8tm eCeSX2JP5v/w2gdb0yxPRdf35+wPYJj7ZRloHO2IirrRwccmoRo1t8XCCHEjU/KeJbRTnub/MQs COE7omvFaY8ONuWNrSs58GwSElzUvJLU= X-Gm-Gg: AfdE7cnTMitiAoI3z/8i2RtqLbyd9PU3V5FLnRAY9EkxjdbyjNJBfsq1fAb10CJJhzk rSm9CwCLx2Yc3dTfHiAKeT4ebydJvf12MhzA63WaIoPfGGZmNisZNMZVoCaXN3jfwXsp5tCEK1k 0v2+a1uw3Pq2pKcRMQ7PlHVGMBSuHucmuaeIKj3FHu98+ge0d+FKkhINK3e48dh3m1aGlkN29qz 6ScTEHq5ssUPe/5g+wj67LmhYzw2V/jBYR4+F8YlqTJs+nrHNp/bd9V2kCtyJjsZIkhu4RH X-Received: by 2002:a05:690c:b87:b0:7fe:bd7:9c93 with SMTP id 00721157ae682-7ffc7c649f1mr41391037b3.44.1781792628941; Thu, 18 Jun 2026 07:23:48 -0700 (PDT) MIME-Version: 1.0 References: <19524-9559d302c8455664@postgresql.org> In-Reply-To: From: Ayush Tiwari Date: Thu, 18 Jun 2026 19:53:37 +0530 X-Gm-Features: AVVi8CcAAKAKW6kqkElQLzIqKKOG-23EfvWKTV7IlQq2uZ0RluSYFW3W2NzGv5k Message-ID: Subject: Re: BUG #19524: In `contrib/btree_gist` float4/float8 GiST index operations, handling NaN values with raw C operator To: =?UTF-8?B?546L6LeD5p6X?= Cc: pgsql-bugs Content-Type: multipart/alternative; boundary="000000000000b6256e065487ec5b" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000b6256e065487ec5b Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi, On Thu, 18 Jun 2026 at 19:32, =E7=8E=8B=E8=B7=83=E6=9E=97 wrote: > In addition to the index scan inconsistency you described, I found two > further security-relevant effects from the same root cause. > > Effect 1: EXCLUDE constraint bypass (float4) > > CREATE TABLE reservations ( > > room float4, > > during tsrange, > > EXCLUDE USING gist (room WITH =3D, during WITH &&) > > ); > > INSERT INTO reservations VALUES ('NaN'::float4, '[2025-01-01,2025-01-02)'= ); > > INSERT INTO reservations VALUES ('NaN'::float4, '[2025-01-01,2025-01-02)'= ); > > SELECT COUNT(*) FROM reservations; > > Expected: 1 (second insert blocked). Actual: 2. The EXCLUDE constraint is > silently bypassed for NaN values, allowing duplicate conflicting rows to = be > inserted. > > Effect 2: RLS bypass (float8) > > CREATE TABLE measurements (id int, val float8); > > CREATE INDEX ON measurements USING gist (val); > > INSERT INTO measurements VALUES (1, 'NaN'), (2, 1.5); > > ALTER TABLE measurements ENABLE ROW LEVEL SECURITY; > > ALTER TABLE measurements FORCE ROW LEVEL SECURITY; > > CREATE POLICY hide_nan ON measurements FOR SELECT USING (val !=3D > 'NaN'::float8); > > CREATE ROLE lowpriv LOGIN; > > GRANT SELECT ON measurements TO lowpriv; > > SET ROLE lowpriv; > > SET enable_seqscan =3D off; > > SET enable_bitmapscan =3D off; > > SELECT * FROM measurements ORDER BY id; > > Expected: only (2, 1.5). Actual: both rows including (1, NaN). The RLS > policy is bypassed when the GiST index is used because > gbt_float8_consistent() sets *recheck =3D false unconditionally, so the > heap-level RLS filter is never applied. > > The root cause is that gbt_float8eq(NaN, NaN) returns false due to IEEE > 754 semantics, causing BtreeGistNotEqualStrategyNumber in > btree_utils_num.c:300 to incorrectly conclude that NaN satisfies !=3D NaN= . > The fix (replacing raw C operators with float8_cmp_internal) addresses bo= th > effects. As an additional defensive measure, *recheck in the consistent > functions should be set to true when the query or key involves NaN. > I meant forwarding this on the other thread (BUG #19501) which has been reported. Regards, Ayush --000000000000b6256e065487ec5b Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

On Thu, 18 Jun 2= 026 at 19:32, =E7=8E=8B=E8=B7=83=E6=9E=97 <violin0613@tju.edu.cn> wrote:

In addition to the index scan inconsist= ency you described, I found two further security-relevant effects from the = same root cause.

Effect 1: EXCLUDE constraint bypass (float4)<= /p>

CREATE TABLE reservations (

room float4,

= during tsrange,

EXCLUDE USING gist (room WITH =3D, during WITH &= amp;&)

);

INSERT INTO reservations VALUES ('NaN'::f= loat4, '[2025-01-01,2025-01-02)');

INSERT INTO reservations V= ALUES ('NaN'::float4, '[2025-01-01,2025-01-02)');

SEL= ECT COUNT(*) FROM reservations;

Expected: 1 (second insert blocked). = Actual: 2. The EXCLUDE constraint is silently bypassed for NaN values, allo= wing duplicate conflicting rows to be inserted.

Effect 2: RLS = bypass (float8)

CREATE TABLE measurements (id int, val float8)= ;

CREATE INDEX ON measurements USING gist (val);

INSERT INTO me= asurements VALUES (1, 'NaN'), (2, 1.5);

ALTER TABLE measureme= nts ENABLE ROW LEVEL SECURITY;

ALTER TABLE measurements FORCE ROW LEV= EL SECURITY;

CREATE POLICY hide_nan ON measurements FOR SELECT USING = (val !=3D 'NaN'::float8);

CREATE ROLE lowpriv LOGIN;

GR= ANT SELECT ON measurements TO lowpriv;

SET ROLE lowpriv;

SET en= able_seqscan =3D off;

SET enable_bitmapscan =3D off;

SELECT * F= ROM measurements ORDER BY id;

Expected: only (2, 1.5). Actual: both r= ows including (1, NaN). The RLS policy is bypassed when the GiST index is u= sed because gbt_float8_consistent() sets *recheck =3D false unconditionally= , so the heap-level RLS filter is never applied.

The root caus= e is that gbt_float8eq(NaN, NaN) returns false due to IEEE 754 semantics, c= ausing BtreeGistNotEqualStrategyNumber in btree_utils_num.c:300 to incorrec= tly conclude that NaN satisfies !=3D NaN. The fix (replacing raw C operator= s with float8_cmp_internal) addresses both effects. As an additional defens= ive measure, *recheck in the consistent functions should be set to true whe= n the query or key involves NaN.

I meant forwarding th= is on the other thread (BUG #19501)
which has=C2=A0been reported.

Regards,
Ay= ush=C2=A0
--000000000000b6256e065487ec5b--