Skip to content

Fix GH-20964, GH-20927: fseek() stream seek with PHP_INT_MIN causes undefined behavior#21433

Open
iliaal wants to merge 1 commit intophp:masterfrom
iliaal:fix/gh-20964-fseek-ubsan
Open

Fix GH-20964, GH-20927: fseek() stream seek with PHP_INT_MIN causes undefined behavior#21433
iliaal wants to merge 1 commit intophp:masterfrom
iliaal:fix/gh-20964-fseek-ubsan

Conversation

@iliaal
Copy link
Contributor

@iliaal iliaal commented Mar 13, 2026

Summary

Stream seek functions in memory, pdo_sqlite, and sqlite3 compute the absolute value of a negative offset using (size_t)(-offset). When offset == ZEND_LONG_MIN, the signed negation overflows -- undefined behavior caught by UBSAN.

The fix swaps the cast order: -(size_t)offset casts to unsigned first (well-defined), then negates (well-defined unsigned arithmetic). Same result for all values, no behavioral change.

Files changed

  • main/streams/memory.c -- php://memory and php://temp stream seek
  • ext/pdo_sqlite/pdo_sqlite.c -- PDO SQLite blob stream seek
  • ext/sqlite3/sqlite3.c -- SQLite3 blob stream seek

Existing PRs

This patch covers all three affected files.

Fixes #20964
Fixes #20927

…fined behavior

Negate after casting to unsigned instead of before, avoiding signed
integer overflow when offset is ZEND_LONG_MIN. The same pattern existed
in the pdo_sqlite and sqlite3 stream seek handlers.

Closes phpGH-20964
Closes phpGH-20927
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

1 participant