Skip to content

Fix signed integer overflow in gzseek64 SEEK_SET normalization (UBSan)#1245

Open
XananasX7 wants to merge 1 commit into
madler:developfrom
XananasX7:fix/gzseek64-signed-integer-overflow
Open

Fix signed integer overflow in gzseek64 SEEK_SET normalization (UBSan)#1245
XananasX7 wants to merge 1 commit into
madler:developfrom
XananasX7:fix/gzseek64-signed-integer-overflow

Conversation

@XananasX7

Copy link
Copy Markdown

Summary

Fix a signed integer overflow (undefined behavior) in gzseek64() when normalizing a SEEK_SET offset.

Root Cause

gzlib.c line 389:

if (whence == SEEK_SET)
    offset -= state->x.pos;  /* UB when offset == INT64_MIN and pos > 0 */

offset and state->x.pos are both z_off64_t (signed 64-bit). When the caller passes offset == INT64_MIN (-9223372036854775808) and the stream has advanced at least one byte (state->x.pos > 0), the subtraction overflows the signed type — undefined behavior per C11 §6.5p5, and flagged by UBSan as runtime error: signed integer overflow.

The intended error path (checking offset < 0 after normalization) is never reached because the overflow wraps to a large positive value, bypassing the bounds check entirely.

Fix

Add an explicit overflow guard before the subtraction:

if (offset < (z_off64_t)(-9223372036854775807LL - 1) + state->x.pos) {
    gz_error(state, Z_STREAM_ERROR, "invalid offset");
    return -1;
}
offset -= state->x.pos;

This preserves all existing semantics for valid offsets and turns the UB into a clean error return.

Fixes #1222.

@Neustradamus

Copy link
Copy Markdown

@XananasX7 XananasX7 force-pushed the fix/gzseek64-signed-integer-overflow branch from 0dd06d2 to 46e6eec Compare June 1, 2026 05:41
@XananasX7

Copy link
Copy Markdown
Author

Friendly ping on this fix for the signed integer overflow in gzseek64 SEEK_SET normalization. The issue is flagged by UBSan. Happy to revise if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Signed Integer Overflow in gzseek64 when Normalizing a SEEK_SET Offset

2 participants