Skip to content

Missing lower-bound check on num_supplies allows heap overflow via malicious cache file #1538

@Tomer-PL

Description

@Tomer-PL

Summary

In backend/snmp-supplies.c:577, num_supplies is read as a signed int via sscanf and checked with num_supplies <= CUPS_MAX_SUPPLIES (32), which allows negative values. When cast to size_t for cupsFileRead(), a negative value wraps to ~SIZE_MAX, causing a massive read into the fixed-size supplies buffer.

Details

// backend/snmp-supplies.c:577-583
if (sscanf(value, "3 %d%d", &num_supplies, &charset) == 2 &&
    num_supplies <= CUPS_MAX_SUPPLIES &&   // -1 <= 32 passes!
    cupsFileGets(cachefile, value, sizeof(value)))
{
    cupsFileRead(cachefile, (char *)supplies,
                 (size_t)num_supplies * sizeof(backend_supplies_t));
    // (size_t)(-1) * 528 = massive value → overflow
}

The cache file is at {CUPS_CACHEDIR}/{printer_ip}.snmp and is written by the SNMP backend itself. Requires lp group write access to the cache directory.

Reproducer

# Create malicious cache file
echo "3 -1 0" > /tmp/test.snmp
echo "test printer" >> /tmp/test.snmp
printf 'A%.0s' {1..4096} >> /tmp/test.snmp

# Test program that reproduces the sscanf + cupsFileRead pattern
# Compile with -fsanitize=address and run

ASan output:

ERROR: AddressSanitizer: negative-size-param: (size=-528)
    #0 memcpy → cupsFileRead (cups/file.c:1503)

Suggested Fix

  if (sscanf(value, "3 %d%d", &num_supplies, &charset) == 2 &&
-     num_supplies <= CUPS_MAX_SUPPLIES &&
+     num_supplies > 0 && num_supplies <= CUPS_MAX_SUPPLIES &&
      cupsFileGets(cachefile, value, sizeof(value)))

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