| From: | PG Bug reporting form <noreply(at)postgresql(dot)org> |
|---|---|
| To: | pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Cc: | 1950233439(at)qq(dot)com |
| Subject: | BUG #19670: Silent Integer Overflow in time_pl_interval() Returns Wrong Time Value |
| Date: | 2026-09-07 14:06:53 |
| Message-ID: | 19670-c4e56832fa6686f8@postgresql.org |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
The following bug has been logged on the website:
Bug reference: 19670
Logged by: Tianyu Shi
Email address: 1950233439(at)qq(dot)com
PostgreSQL version: 19beta3
Operating system: Ubuntu22.04
Description:
### Summary
`time_pl_interval()` in `src/backend/utils/adt/date.c` (lines 2174–2195)
silently produces incorrect results when adding a near-maximal interval to a
time value. The infinity guard (`INTERVAL_NOT_FINITE`) requires all three
interval fields to simultaneously hold their extreme values, so an interval
such as `'9223372036854 seconds'` (where `span->time = 9223372036854000000`,
slightly below `INT64_MAX`) bypasses the check entirely. The subsequent
unchecked addition `result = time + span->time` overflows signed 64-bit
integer arithmetic (C undefined behavior), returning a garbage `TimeADT`
with no error raised. Applications relying on correct time arithmetic for
security decisions — session expiry, scheduling windows, access-time
enforcement — may silently receive a corrupted value and act on it.
### PoC
Any authenticated database user can trigger the overflow with a single SQL
statement; no special privileges are required.
```sql
SELECT '23:59:59.999999'::time + interval '9223372036854 seconds';
```
To run against the local build:
```sql
-- Connect: ./build/bin/psql -h ./build/run -p 5432 postgres
SELECT
'23:59:59.999999'::time + interval '9223372036854 seconds' AS
actual_result,
make_time(0, 0, 0) + 24053999999::bigint * interval '1 microsecond' AS
expected_result,
CASE
WHEN ('23:59:59.999999'::time + interval '9223372036854 seconds') !=
(make_time(0, 0, 0) + 24053999999::bigint * interval '1
microsecond')
THEN 'MISMATCH: Integer overflow confirmed - result is WRONG'
ELSE 'MATCH: No overflow detected'
END AS verdict;
```
### Result
Expected output (correct modular arithmetic): `06:40:53.999999`.
Actual output observed: `19:59:04.448383` — an overflow-corrupted value
returned without any error or warning.
```
actual_result | expected_result | verdict
-----------------+-----------------+--------------------------------------------------------
19:59:04.448383 | 06:40:53.999999 | MISMATCH: Integer overflow confirmed -
result is WRONG
```
The semantic invariant `(time + interval) mod USECS_PER_DAY` is violated. No
exception is raised, so callers cannot distinguish a correct result from a
corrupted one.
| From | Date | Subject | |
|---|---|---|---|
| Next Message | PG Bug reporting form | 2026-09-07 14:09:09 | BUG #19671: IPv4 CIDR Prefix Integer Overflow Bypasses Validation in inet/cidr Casts |
| Previous Message | PG Bug reporting form | 2026-09-07 11:51:29 | BUG #19664: nbtree: Assertion failure when a custom index AM reuses bthandler |