libcupsfilters validates enum-like job options against printer-reported *-supported
capability attributes on supported driverless and helper paths. In the audited code,
cfIPPAttrEnumValForPrinter() resolves the matching printer capability attribute by name
using IPP_TAG_ZERO, then iterates through its values and feeds ippGetString() results
directly into strcasecmp(). Despite the helper name, cfIPPAttrEnumValForPrinter()
returns the selected attribute value as a string.
This creates a crashable semantic type-confusion during the processing of untrusted
printer capability data. While network daemons like cups-browsed may validate
attributes via ippValidateAttributes() prior to ingestion, local parsing of malformed IPP
files or bypassed network validation will trigger the flaw. As confirmed by the
OpenPrinting maintainers, because libcupsfilters is a library and the caller provides the
attributes, this manifests as a local application crash rather than a service-level DoS.
Affected File:
https://github.com/OpenPrinting/libcupsfilters/blob/3ee9507/cupsfilters/ipp.c
Affected Code:
const char *
cfIPPAttrEnumValForPrinter(
ipp_t *printer_attrs, // I - Printer attributes (from get-printer-attributes or NULL)
ipp_t *job_attrs, // I - Job attributes
const char *attr_name) // I - Attribute name
// O - Attribute value as string
{
ipp_attribute_t *attr;
char printer_attr_name[256];
int i;
const char *res;
// Validate input parameters
if ((printer_attrs == NULL && job_attrs == NULL) || attr_name == NULL)
return NULL;
// Check if job has the named attribute and get its value as string
if (job_attrs == NULL ||
(attr = ippFindAttribute(job_attrs, attr_name, IPP_TAG_ZERO)) == NULL) {
res = NULL;
} else {
res = ippGetString(attr, 0, NULL);
}
if (printer_attrs) {
if (res && res[0]) {
// Check if value is valid according to printer attributes
snprintf(printer_attr_name, sizeof(printer_attr_name) - 1,
"%s-supported", attr_name);
if ((attr = ippFindAttribute(printer_attrs, printer_attr_name,
IPP_TAG_ZERO)) != NULL) {
for (i = 0; i < ippGetCount(attr); i++) {
if (strcasecmp(res, ippGetString(attr, i, NULL)) == 0)
break; // Job attribute value is valid
}
if (i == ippGetCount(attr))
res = NULL; // Job attribute value is not valid
}
}
if (!res || !res[0]) {
// Use default value if no valid value found
snprintf(printer_attr_name, sizeof(printer_attr_name) - 1,
"%s-default", attr_name);
if ((attr = ippFindAttribute(printer_attrs, printer_attr_name,
IPP_TAG_ZERO)) != NULL)
res = ippGetString(attr, 0, NULL);
}
}
return res;
}
To mitigate this issue, it is recommended to request the expected string-compatible tag
or tags explicitly for *-supported attributes instead of using IPP_TAG_ZERO where
feasible. Every ippGetString() result should be checked before it is passed into
strcasecmp() or similar string-only logic, and wrong-tag capability attributes should be
treated as invalid printer data
libcupsfilters validates enum-like job options against printer-reported *-supported
capability attributes on supported driverless and helper paths. In the audited code,
cfIPPAttrEnumValForPrinter() resolves the matching printer capability attribute by name
using IPP_TAG_ZERO, then iterates through its values and feeds ippGetString() results
directly into strcasecmp(). Despite the helper name, cfIPPAttrEnumValForPrinter()
returns the selected attribute value as a string.
This creates a crashable semantic type-confusion during the processing of untrusted
printer capability data. While network daemons like cups-browsed may validate
attributes via ippValidateAttributes() prior to ingestion, local parsing of malformed IPP
files or bypassed network validation will trigger the flaw. As confirmed by the
OpenPrinting maintainers, because libcupsfilters is a library and the caller provides the
attributes, this manifests as a local application crash rather than a service-level DoS.
Affected File:
https://github.com/OpenPrinting/libcupsfilters/blob/3ee9507/cupsfilters/ipp.c
Affected Code:
To mitigate this issue, it is recommended to request the expected string-compatible tag
or tags explicitly for *-supported attributes instead of using IPP_TAG_ZERO where
feasible. Every ippGetString() result should be checked before it is passed into
strcasecmp() or similar string-only logic, and wrong-tag capability attributes should be
treated as invalid printer data