Skip to content

fix heap overflow in ppdEmitString custom value buffer sizing - #1656

Closed
aizu-m wants to merge 1 commit into
OpenPrinting:masterfrom
aizu-m:ppd-emit-custom-value-size
Closed

fix heap overflow in ppdEmitString custom value buffer sizing#1656
aizu-m wants to merge 1 commit into
OpenPrinting:masterfrom
aizu-m:ppd-emit-custom-value-size

Conversation

@aizu-m

@aizu-m aizu-m commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

ASan, printing with -o PageSize=Custom.340282346638528859811704183484516925440x340282346638528859811704183484516925440:

==93781==ERROR: AddressSanitizer: heap-buffer-overflow
WRITE of size 1 at 0x611000002cc9 thread T0
    #0 cupsCopyString string.c:105
    #1 ppdEmitString ppd-emit.c:1077
0x611000002cc9 is located 0 bytes after 201-byte region [0x611000002c00,0x611000002cc9)

Came out of reading the sizing loop next to the emit loop. Sizing reserves 10 bytes per custom number and 50 for the five CustomPageSize numbers. Emission goes through _cupsStrFormatd, which formats %.12f, so a float takes up to 39 integer digits, 53 characters with sign and fraction. Nothing clamps the value first: ppdPageSize reads Custom.WIDTHxLENGTH straight out of the job option without checking custom_min/custom_max, and ppd_mark_option stores custom real/points/int parameters the same way.

Past the reservation bufptr runs beyond bufend, and the writes after the numbers carry no bound: the newline after each number, the memcpy of the choice code at :1070, and the (size_t)(bufend - bufptr + 1) length at :1077 that underflows to SIZE_MAX. A custom option with three real parameters is worse:

WRITE of size 32 at 0x612000001dc3
    #0 memcpy
    #1 ppdEmitString ppd-emit.c:1070
0x612000001dc3 is located 0 bytes after 259-byte region

The JCL branch undercounts the same way, but its emit loop is bounded, so there it only truncates. All three reservations now use the real %.12f width. No behaviour change for in-range values; the new testppd case fails on master and passes here.

Signed-off-by: Aizal Khan <aizumusheer2@gmail.com>

@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.

There is a difference between real values that will be used for printing (with much much smaller limits on the supported values) vs. synthetic test values you use to try to break things.

Seems like the proper solution here is to set an upper limit of characters per number and then use that vs. using wildly inflated memory reservation that has its own issues (i.e. OOM crashes).

@michaelrsweet michaelrsweet self-assigned this Jul 30, 2026
@michaelrsweet michaelrsweet added the bug Something isn't working label Jul 30, 2026
@michaelrsweet michaelrsweet added this to the v2.4.x milestone Jul 30, 2026
@michaelrsweet

Copy link
Copy Markdown
Member

I pushed an alternate fix that limits each number to MAX_CUSTOM_DIGITS which is defined as 9, which limits custom page sizes to about 219 statute miles or 353km:

[master 00eef0e] Better limit the size of custom numbers in PS option output (Issue #1656)

[2.4.x b125eff] Better limit the size of custom numbers in PS option output (Issue #1656)

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants