Skip to content

fix(pdftoraster): OOB read and NULL-ptr write in write_page_image()#146

Open
kimaiden1984-boop wants to merge 1 commit intoOpenPrinting:masterfrom
kimaiden1984-boop:fix/pdftoraster-copy-height-oob
Open

fix(pdftoraster): OOB read and NULL-ptr write in write_page_image()#146
kimaiden1984-boop wants to merge 1 commit intoOpenPrinting:masterfrom
kimaiden1984-boop:fix/pdftoraster-copy-height-oob

Conversation

@kimaiden1984-boop
Copy link
Copy Markdown

Fix two memory safety bugs introduced by commit 0ad5d2a ("fix padding issue") in the write_page_image() function, which trigger when the rendered PDF image is smaller than the output page:

  1. Heap-buffer-overflow (READ): The forward copy loop used h <= copy_height instead of h < copy_height, causing one extra row iteration past the allocated colordata buffer. This OOB data flows through lcms2 color conversion and leaks into the CUPS raster output.
  2. NULL-pointer Dereference (WRITE): Unconditional memset(lineBuf, ...) was called without checking doc->allocLineBuf. When select_special_case() sets allocLineBuf=false (affecting 14 color spaces), lineBuf is NULL and the memset causes a SEGV crash.

(Note: The reverse/duplex loop condition h <= copy_height at line 1981 remains unchanged. It is correct because h descends from page_height to 1, meaning h == copy_height processes the last valid row at index copy_height - 1 with no subsequent OOB read.)

Testing Performed:
Added a self-contained unit test that validates both fixes across 5 scenarios for both forward and reverse loops:

  • image < page
  • image == page
  • image > page
  • image = 0 (edge case)
  • allocLineBuf = false

Fix two bugs introduced by commit 0ad5d2a ("fix padding issue") in the
write_page_image() function when the rendered PDF image is smaller than
the output page:

1. Heap-buffer-overflow READ (CVE candidate): The forward copy loop used
   h <= copy_height instead of h < copy_height, causing one extra row
   iteration past the allocated colordata buffer. The OOB data flows
   through lcms2 color conversion into the CUPS raster output.

2. NULL-ptr WRITE (DoS): Unconditional memset(lineBuf, ...) without
   checking doc->allocLineBuf. When select_special_case() sets
   allocLineBuf=false (14 color spaces), lineBuf is NULL and the
   memset crashes with SEGV.

The reverse/duplex loop condition h <= copy_height is correct because
h descends from page_height to 1, so h == copy_height processes the
last valid row (index copy_height-1) with no subsequent OOB read.

A self-contained unit test is added that validates both fixes across
5 scenarios (image<page, image==page, image>page, image=0 edge case,
allocLineBuf=false) for both forward and reverse loops.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.

1 participant