| From: | Kirill Reshke <reshkekirill(at)gmail(dot)com> |
|---|---|
| To: | 1950233439(at)qq(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Subject: | Re: BUG #19673: inetmi_int8 Signed Integer Overflow Returns Wrong IPv6 Address |
| Date: | 2026-10-29 13:49:04 |
| Message-ID: | CALdSSPgDgvuUCsGqmGibjW-3DfN88+kOHHK_gfYRP9R+vtx45A@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
On Thu, 10 Sept 2026 at 17:11, PG Bug reporting form
<noreply(at)postgresql(dot)org> wrote:
>
> The following bug has been logged on the website:
>
> Bug reference: 19673
> Logged by: Tianyu Shi
> Email address: 1950233439(at)qq(dot)com
> PostgreSQL version: 19beta3
> Operating system: Ubuntu22.04
> Description:
>
> ### Summary
>
> In `inetmi_int8()` (`src/backend/utils/adt/network.c`, line 1946), the
> expression `-addend` triggers signed integer overflow (C11 undefined
> behavior) when `addend == INT64_MIN`. On x86-64, the CPU wraps the negation
> back to `INT64_MIN`, causing the function to compute `ip - 2^63` instead of
> the correct `ip + 2^63`. For IPv6 addresses, the overflow-detection path in
> `internal_inetpl()` does not catch this case, so the function silently
> returns a completely wrong address rather than raising an error.
> Applications that use `inet - int8` to compute IPv6 subnet boundaries may
> therefore derive incorrect range endpoints, potentially causing
> access-control decisions to accept or reject the wrong addresses.
>
> ### PoC
>
> Any unprivileged user can trigger the bug with a single SQL statement using
> the `inet - int8` operator and `INT64_MIN` as the subtrahend.
>
> ```sql
> -- Connect as any normal (non-superuser) role.
> -- INT64_MIN must be passed as a string cast to avoid parse-time overflow.
>
> -- Trigger: should compute 8000::1 + 2^63 = 8000::8000:0:0:1, but silently
> returns a lower address.
> SELECT '8000::1'::inet - '-9223372036854775808'::int8 AS trigger_result;
>
> -- Roundtrip invariant: (X - INT64_MIN) + INT64_MIN must equal X.
> SELECT
> '8000::1'::inet
> AS original,
> '8000::1'::inet - '-9223372036854775808'::int8
> AS minus_int64min,
> ('8000::1'::inet - '-9223372036854775808'::int8) +
> '-9223372036854775808'::int8 AS roundtrip,
> (('8000::1'::inet - '-9223372036854775808'::int8) +
> '-9223372036854775808'::int8)
> = '8000::1'::inet
> AS roundtrip_correct;
>
> -- Direction invariant: subtracting a negative must increase the address.
> SELECT
> '8000::1'::inet AS
> original,
> '8000::1'::inet - '-9223372036854775808'::int8 AS
> result,
> ('8000::1'::inet - '-9223372036854775808'::int8) > '8000::1'::inet AS
> direction_increased;
> ```
>
> ### Result
>
> Expected: `'8000::1'::inet - INT64_MIN` = `ip + 2^63` = `8000::8000:0:0:1`
> (address increases).
> Actual: the function returns `7fff:ffff:ffff:ffff:8000::1`, which is *less*
> than the original address — the arithmetic went in the wrong direction with
> no error raised.
>
> All three semantic invariants are violated:
>
> ```
> original | minus_int64min | roundtrip |
> roundtrip_correct
> ----------+-----------------------------+------------------------+-------------------
> 8000::1 | 7fff:ffff:ffff:ffff:8000::1 | 7fff:ffff:ffff:ffff::1 | f
>
> original | result | direction_increased
> ----------+-----------------------------+---------------------
> 8000::1 | 7fff:ffff:ffff:ffff:8000::1 | f
> ```
>
> `roundtrip_correct = f` and `direction_increased = f` confirm that
> `inetmi_int8()` computed `ip - 2^63` instead of `ip + 2^63` due to the
> signed integer overflow of `-INT64_MIN` on x86-64.
>
>
Hi!
There are additional erroneous cases.
For the full range of the IPv6 address space the true mathematical
difference is 2^128-1. However its byte reprization is all 0xFF
which looks like the sign truncated result. Operator silently returns
-1 / 1:
SELECT inet 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' - inet '::';
?column?
----------
-1
SELECT inet '::' - inet 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff';
?column?
----------
1
expected is 22003 (result is out of range) in both
I didn't go with any patch for this, but in case anyone do, that's
something we need to handle too
--
Best regards,
Kirill Reshke
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Dilip Kumar | 2026-10-29 14:23:43 | Re: BUG #19791: ALTER COLUMN TYPE fails on an INCLUDE column of an index used by a foreign key |
| Previous Message | Jeevan Chalke | 2026-10-29 13:24:02 | Re: BUG #19384: Server crash at textout |