agora inbox for pgsql-bugs@postgresql.org
help / color / mirror / Atom feedFrom: PG Bug reporting form <noreply@postgresql.org>
To: pgsql-bugs@lists.postgresql.org
Cc: 1950233439@qq.com
Subject: BUG #19672: int8shl/int8shr Undefined Behavior on Out-of-Range Shift Amounts
Date: Mon, 07 Sep 2026 14:10:42 +0000
Message-ID: <19672-33e7d9d1be2229ea@postgresql.org> (raw)
The following bug has been logged on the website:
Bug reference: 19672
Logged by: Tianyu Shi
Email address: 1950233439@qq.com
PostgreSQL version: 19beta3
Operating system: Ubuntu22.04
Description:
### Summary
`int8shl()` and `int8shr()` in `src/backend/utils/adt/int8.c` (lines
1255–1270) apply `arg1 << arg2` and `arg1 >> arg2` directly on `int64`
without validating the shift amount `arg2`. Under C11 §6.5.7, shifting by a
negative count, by a count ≥ 64, or left-shifting a signed value into
overflow are all undefined behavior. Every other bigint arithmetic operator
in PostgreSQL (`+`, `-`, `*`, unary `-`) raises `ERROR: bigint out of range`
on overflow, making the shift operators the sole exception and creating a
semantic inconsistency that can silently corrupt permission bitmasks or
financial calculations.
### PoC
Pure SQL — any authenticated database user can trigger the issue without
special privileges.
```sql
-- Shift count >= bit width: returns 1 instead of 0 or ERROR
SELECT 1::bigint << 64;
-- Negative shift count: returns INT64_MIN instead of ERROR
SELECT 1::bigint << -1;
-- Left-shift MAX_INT64 by 1: silently returns -2 instead of raising "bigint
out of range"
SELECT 9223372036854775807::bigint << 1;
-- Differential: multiplication raises a proper error for the same value
SELECT 9223372036854775807::bigint * 2;
-- ERROR: bigint out of range
-- Negative right-shift: returns 0 instead of ERROR
SELECT 1::bigint >> -1;
-- Right-shift count >= bit width: returns 1 instead of 0 or ERROR
SELECT 1::bigint >> 64;
```
```bash
# Initialize and start a UBSAN-instrumented PostgreSQL instance
./build/bin/initdb -D pgdata --no-locale -E UTF8
mkdir -p ./build/run
./build/bin/pg_ctl -D pgdata -l pgdata/postgres.log \
-o "-p 55433 -k ./build/run" start
# Run the PoC queries (Test 4 will error; that is expected)
./build/bin/psql -h ./build/run -p 55433 postgres <<'EOF'
SELECT 1::bigint << 64;
SELECT 1::bigint << -1;
SELECT 9223372036854775807::bigint << 1;
SELECT 9223372036854775807::bigint * 2;
SELECT 1::bigint >> -1;
SELECT 1::bigint >> 64;
EOF
# Inspect server log for UBSAN output
grep -E "runtime error|UndefinedBehaviorSanitizer|SUMMARY"
pgdata/postgres.log
./build/bin/pg_ctl -D pgdata stop
```
### Result
UndefinedBehaviorSanitizer fired in the PostgreSQL server log at both shift
sites: `int8.c:1260:2: runtime error: shift exponent 64 is too large for
64-bit type 'int64' (aka 'long')` and `int8.c:1269:2: runtime error: shift
exponent -1 is negative`. The SQL output confirms wrong values: `1::bigint
<< 64` returns `1` (expected `0` or error), `1::bigint << -1` returns
`-9223372036854775808` (expected error), and `9223372036854775807::bigint <<
1` returns `-2` (expected `ERROR: bigint out of range`). The differential
confirms the inconsistency: `9223372036854775807::bigint * 2` correctly
raises `ERROR: bigint out of range`, while the semantically equivalent
left-shift silently wraps.
Message-ID: <19672-33e7d9d1be2229ea@postgresql.org>
Permalink: ../19672-33e7d9d1be2229ea@postgresql.org/
Also on: postgresql.org/message-id/19672-33e7d9d1be2229ea@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 #19672: int8shl/int8shr Undefined Behavior on Out-of-Range Shift Amounts
In-Reply-To: <19672-33e7d9d1be2229ea@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