Skip to content

Heap buffer overflow in rastertoepson PackBits compression (CompBuffer undersized for RGB) #1537

@Tomer-PL

Description

@Tomer-PL

Summary

The rastertoepson filter allocates CompBuffer based on cupsWidth but fills it with cupsBytesPerLine bytes of PackBits-compressed data. For RGB color space (NumPlanes=1, cupsBitsPerPixel=24), cupsBytesPerLine = 3 * cupsWidth, but CompBuffer = calloc(2, cupsWidth + 1). Worst-case PackBits output for non-repeating RGB data overflows the buffer by ~1,094 bytes.

Details

Allocation (filter/rastertoepson.c:301):

CompBuffer = calloc(2, header->cupsWidth + 1);
// For cupsWidth=1071: allocates 2144 bytes

Fill (filter/rastertoepson.c:779):

bytes = header->cupsBytesPerLine / NumPlanes;
// For RGB (NumPlanes=1): bytes = 3*cupsWidth = 3213

The PackBits compression loop at lines 493-548 processes 3213 bytes of input into a 2144-byte buffer. Non-repeating input data produces ~3238 bytes of output, overflowing by ~1094 bytes.

Compare with filter/rastertohp.c:341 which correctly uses cupsBytesPerLine:

CompBuffer = malloc(header->cupsBytesPerLine * 2 + 2);  // Correct

Reproducer

Compile and run with AddressSanitizer:

# Build filter with ASan
gcc -g -O0 -fsanitize=address -I. -L./cups -Wl,-rpath,./cups \
    -o rastertoepson_asan filter/rastertoepson.c -lcups -lcupsimage

# Generate crafted raster (RGB, non-repeating pixels, PackBits compression)
# cupsWidth=1071, cupsBitsPerPixel=24, cupsCompression=1
# [see gen_epson_overflow.c in description]

# Run
./rastertoepson_asan 1 user title 1 '' < /tmp/crafted.ras > /dev/null

ASan output:

ERROR: AddressSanitizer: heap-buffer-overflow
WRITE of size 127 at CompressData (rastertoepson.c:546)
0 bytes after 2144-byte region allocated at StartPage (rastertoepson.c:301)

Production crash (without ASan):

free(): invalid next size (normal)
PID crashed on signal 6

Suggested Fix

- CompBuffer = calloc(2, header->cupsWidth + 1);
+ CompBuffer = calloc(2, header->cupsBytesPerLine + 1);

This matches the pattern used by rastertohp.c which correctly bases the buffer size on cupsBytesPerLine.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions