| From: | Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com> |
|---|---|
| To: | 1217816127(at)qq(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Subject: | Re: BUG #19603: Vuln47: distance_taxicab and distance_chebyshev silently return 0 instead of NaN when a cube coordin |
| Date: | 2026-08-03 13:16:56 |
| Message-ID: | CAJTYsWVq0zmdkKpjpRFEeQf1AddvKeYt3pRHZ7KqPmda=joc0g@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
Hi,
On Mon, 3 Aug 2026 at 17:21, PG Bug reporting form <noreply(at)postgresql(dot)org>
wrote:
> The following bug has been logged on the website:
>
> Bug reference: 19603
> Logged by: Yuelin Wang
> Email address: 1217816127(at)qq(dot)com
> PostgreSQL version: 19beta2
> Operating system: Linux (Ubuntu 24.04, x86_64)
> Description:
>
> ### Summary
>
> The static helper distance_1D() in contrib/cube/cube.c classifies two
> intervals as "left of", "right of", or "intersecting" using direct floating
> point comparisons. When a coordinate is NaN, every comparison evaluates to
> false, so the interval falls through to the intersecting branch and the
> function returns 0.0 instead of NaN. distance_taxicab and
> distance_chebyshev
> call distance_1D per dimension and sum or max the results, so a single NaN
> coordinate silently produces a finite, plausible-looking distance instead
> of
> propagating NaN as IEEE 754 arithmetic normally would.
>
> CWE: CWE-1339. Severity: Low.
>
> ### PoC
>
> ```sql
> CREATE EXTENSION cube;
> SELECT distance_chebyshev('(nan,nan)'::cube, '(1,1)'::cube);
> SELECT distance_chebyshev('(5,5)'::cube, '(1,nan)'::cube);
> SELECT distance_taxicab('(nan)'::cube, '(1)'::cube);
> ```
>
> ### Result
>
> Real captured output from the independent verification run:
>
> ```
> CREATE EXTENSION
> distance_chebyshev
> --------------------
> 0
> (1 row)
>
> distance_chebyshev
> --------------------
> 4
> (1 row)
>
> distance_taxicab
> ------------------
> 0
> (1 row)
> ```
>
> ### Impact
>
> A database user who stores or queries cube values containing NaN
> coordinates
> can get silently wrong distance results (e.g. 0 instead of NaN) from
> distance_taxicab and distance_chebyshev, which can corrupt nearest-neighbor
> search results, ranking, or KNN-index-backed queries that rely on these
> operators.
>
Thanks for the report and repro.
It looks to me like the root is distance_1D(): with a NaN coordinate none of
its comparisons can be true, so it seems to fall through to the overlapping
case and return 0. My first thought was to fix it there and return NaN when
any endpoint is NaN, which seems enough for taxicab and Euclidean (<->),
which
accumulate with +=. Chebyshev needs a bit more, since its running max uses
"d > distance" and NaN > x is false, so I added an explicit NaN check there
too.
Regards,
Ayush
| Attachment | Content-Type | Size |
|---|---|---|
| 0001-cube-propagate-NaN-in-taxicab-Chebyshev-and-Euclidea.patch | application/octet-stream | 5.0 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Andrey Rachitskiy | 2026-08-03 13:35:51 | Re: BUG #19607: Bug 18: `pg_surgery` infinite loop in `heap_force_common` |
| Previous Message | Aleksander Alekseev | 2026-08-03 12:55:12 | Re: BUG #19604: Bug 9: `plperl_to_hstore` heap overflow with a tied Perl hash |