agora inbox for pgsql-bugs@postgresql.org  
help / color / mirror / Atom feed
From: PG Bug reporting form <noreply@postgresql.org>
To: pgsql-bugs@lists.postgresql.org
Cc: 1950233439@qq.com
Subject: BUG #19671: IPv4 CIDR Prefix Integer Overflow Bypasses Validation in inet/cidr Casts
Date: Mon, 07 Sep 2026 14:09:09 +0000
Message-ID: <19671-9b75c5d8b03fd33b@postgresql.org> (raw)

The following bug has been logged on the website:

Bug reference:      19671
Logged by:          Tianyu Shi
Email address:      1950233439@qq.com
PostgreSQL version: 19beta3
Operating system:   Ubuntu22.04
Description:        

### Summary

In `src/backend/utils/adt/inet_net_pton.c`, both `inet_cidr_pton_ipv4()`
(lines 177–188) and `inet_net_pton_ipv4()` (lines 296–308) accumulate the
CIDR prefix length digit-by-digit with no per-digit overflow guard, allowing
a 32-bit signed `int bits` to wrap silently on inputs such as `4294967297`
(2³²+1 → 1). The post-loop check `if (bits > 32) goto emsgsize` then sees
the wrapped value and passes it, causing any non-privileged SQL user to
store `inet`/`cidr` values with silently corrupted prefix lengths. An
attacker who can INSERT into a table with an `inet`/`cidr` column, or supply
a cast literal, can produce entries whose stored masklen differs arbitrarily
from what was written, potentially bypassing application-layer ACL logic
built on PostgreSQL subnet-containment operators.

### PoC

No superuser required; any user able to execute a `SELECT` or `INSERT` with
an `inet`/`cidr` cast is sufficient.

```sql
\set ON_ERROR_STOP off

-- Test 1: inet cast — 4294967297 = 2^32+1 wraps to 1; should ERROR but does
not
SELECT masklen('1.2.3.4/4294967297'::inet) AS actual_masklen;
-- Observed: 1   Expected: ERROR

-- Test 2: cidr cast — 4294967296 = 2^32 wraps to 0; should ERROR but does
not
SELECT masklen('0.0.0.0/4294967296'::cidr) AS actual_masklen;
-- Observed: 0   Expected: ERROR

-- Control: legitimate out-of-range /33 is correctly rejected
SELECT masklen('1.2.3.4/33'::inet) AS should_error;
-- Observed: ERROR: invalid input syntax for type inet: "1.2.3.4/33"

-- Stored value demonstration
SELECT host('1.2.3.4/4294967297'::inet)    AS inet_host,
       masklen('1.2.3.4/4294967297'::inet) AS inet_masklen_actual,
       1                                    AS inet_masklen_expected;
-- Returns: 1.2.3.4 | 1 | 1  (value accepted and stored with wrong prefix)
```

### Result

- `'1.2.3.4/4294967297'::inet` — expected `ERROR: invalid mask length`;
actual `masklen() = 1` (2³²+1 wraps to 1, bypass confirmed).
- `'0.0.0.0/4294967296'::cidr` — expected `ERROR: invalid mask length`;
actual `masklen() = 0` (2³² wraps to 0, bypass confirmed).
- `'1.2.3.4/33'::inet` — correctly raises `ERROR: invalid input syntax for
type inet: "1.2.3.4/33"` (normal in-range bound check works).

The asymmetry demonstrates that only the integer-overflow path escapes
validation: overflowing prefix literals are silently accepted and stored
with a wrong (wrapped) prefix length, while a straightforward out-of-range
value is rejected. Any application relying on `<<` / `<<=` subnet
comparisons against stored `inet`/`cidr` values is exposed to logic bypass
via entries whose effective mask is broader than intended.







view thread (6+ messages)  latest in thread

Message-ID: <19671-9b75c5d8b03fd33b@postgresql.org>
Permalink:  ../19671-9b75c5d8b03fd33b@postgresql.org/
Also on:    postgresql.org/message-id/19671-9b75c5d8b03fd33b@postgresql.org

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-bugs@postgresql.org
  Cc: noreply@postgresql.org, pgsql-bugs@lists.postgresql.org, 1950233439@qq.com
  Subject: Re: BUG #19671: IPv4 CIDR Prefix Integer Overflow Bypasses Validation in inet/cidr Casts
  In-Reply-To: <19671-9b75c5d8b03fd33b@postgresql.org>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox