Skip to content

fix stack underflow in ippAddStringfv/ippSetStringfv truncation - #1664

Closed
aizu-m wants to merge 1 commit into
OpenPrinting:masterfrom
aizu-m:ipp-stringf-truncate-underflow
Closed

fix stack underflow in ippAddStringfv/ippSetStringfv truncation#1664
aizu-m wants to merge 1 commit into
OpenPrinting:masterfrom
aizu-m:ipp-stringf-truncate-underflow

Conversation

@aizu-m

@aizu-m aizu-m commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Turned up while fuzzing the string constructors with malformed UTF-8.

AddressSanitizer, testipp calling ippAddStringf() with a value that is all 0x80 continuation bytes and a length-limited tag:

==ERROR: AddressSanitizer: stack-buffer-underflow, WRITE of size 1
    #0 ippAddStringfv ipp.c:1098
    #1 ippAddStringf  ipp.c:960
    #2 main           testipp.c:906
'buffer' (line 1008) <== Memory access at offset 31 underflows this variable
SUMMARY: stack-buffer-underflow ipp.c:1098 in ippAddStringfv

When an over-long value is trimmed to the tag maximum at a UTF-8 boundary, the inner loop that skips continuation bytes is bounded by bufptr > buffer, but the outer bufptr -- that follows it is not. A value whose first max_bytes bytes are all continuation bytes (no lead byte) walks bufptr down to buffer, the outer decrement then drops it to buffer - 1, the while (bufptr > bufmax) exits, and *bufptr = '\0' stores one byte below the array. As a side effect the value is also left untrimmed.

ippSetStringfv carries the same block, so both get the guard. It only mirrors what the inner loop already does. Added a testipp case that fails before the change (value not trimmed) and passes after.

@michaelrsweet michaelrsweet self-assigned this Aug 10, 2026
@michaelrsweet michaelrsweet added the investigating Investigating the issue label Aug 10, 2026
@michaelrsweet michaelrsweet added this to the v2.5 milestone Aug 10, 2026
@michaelrsweet

Copy link
Copy Markdown
Member

Investigating...

(Please use your GPG key to sign commits for this repository...)

When trimming an over-long value to the tag maximum at a UTF-8 boundary, the inner loop skips continuation bytes bounded by bufptr > buffer but the outer decrement after it does not, so a value made only of continuation bytes walks bufptr to buffer - 1 and *bufptr = '\0' writes one byte below the stack buffer. Guard the outer decrement like the inner loop already does, in both functions.

Signed-off-by: Aizal Khan <aizumusheer2@gmail.com>
@aizu-m
aizu-m force-pushed the ipp-stringf-truncate-underflow branch from ce61ed1 to 2b2d523 Compare August 18, 2026 10:41
@aizu-m

aizu-m commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

Re-pushed the same commit signed with my GPG key, shows as verified now. No code changes, just the signature.

@michaelrsweet michaelrsweet left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good on libcups changes, don't want the unit test noise.

@michaelrsweet

Copy link
Copy Markdown
Member

[master 6f30dcc] Fix potential buffer underflow issue in ippAdd/SetStringf(v) (Issue #1664)

[2.4.x 76bac38] Fix potential buffer underflow issue in ippAdd/SetStringf(v) (Issue #1664)

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

Labels

investigating Investigating the issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants