CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N
Summary
The CUPS scheduler (cupsd) was vulnerable to a heap-based buffer overflow corrupting adjacent memory blocks. The flaw resides in how the scheduler calculates the required memory for job attributes versus how it actually serializes them. Specifically, the ipp_length() function fails to account for URI attributes like job-uuid, leading to an undersized allocation in get_options(). An unauthenticated remote attacker can exploit this by sending a crafted IPP request with an overly long job-uuid, resulting in memory corruption, crashing of the scheduler process, creating a Denial of Service (DoS).
Impact
- Denial of Service (DoS): The vulnerability is trivial to trigger, allowing any network-adjacent user to crash the printing service.
- Heap Corruption: Attacker-controlled data is written past the buffer boundaries, resulting in memory instability and process termination.
- Service Disruption: A single malicious payload can disable the printing system for all users until the service is restarted.
Description
The vulnerability stems from a logical discrepancy between the size calculation and the actual data copy in scheduler/job.c.
1. Incorrect Size Calculation
The ipp_length() function iterates through attributes to determine the buffer size. It explicitly skips IPP_TAG_URI types, which includes the job-uuid attribute.
for (attr = ipp->attrs; attr != NULL; attr = attr->next)
{
if (attr->value_tag == IPP_TAG_NOVALUE ||
attr->value_tag == IPP_TAG_URI || // Skipped!
attr->value_tag == IPP_TAG_URISCHEME)
continue;
...
}
2. Undersized Allocation & Unsafe Copy
In get_options(), the buffer is allocated based on this incorrect length. However, the serialization loop makes an exception for job-uuid and job-authorization-uri, copying them into the buffer without any bounds checking.
case IPP_TAG_URI:
for (valptr = attr->values[i].string.text; *valptr;)
{
if (strchr(" \t\n\\'\"", *valptr))
*optptr++ = '\\'; // Overflow!
*optptr++ = *valptr++; // Overflow!
}
*optptr = '\0';
break;
Since job-uuid can be up to 32,767 bytes per the IPP protocol, and cupsd does not validate its length before processing, an attacker has precise control over the overflow size and content, directly leading to heap corruption.
Conclusion
This vulnerability highlights the critical importance of size-calculation logic and data-copy logic in synchronization. In the case of CUPS, a single missing tag check in a utility function created an attack vector for out-of-bounds write in the scheduler's heap memory. Users should ensure that CUPS services are not exposed to untrusted networks and as there is no patch from the OpenPrinting project at the time of this blogpost.
References
Special thanks to the OpenPrinting maintainers for their diligence in managing this security disclosure.