cups/SOURCES/cups-cve202010001.patch

62 lines
2.4 KiB
Diff

Fix for CVE-2020-10001, which is a bug in the CUPS ippReadIO function when it
reads tagged string values (nameWithLanguage and textWithLanguage). The
previous code verified that the length of the sub-strings (language identifier
and name/text value) did not exceed the size of the allocated buffer (1 byte
larger than the maximum IPP value size of 32767 bytes), but did not validate
against the length of the actual IPP value.
The issues introduced by this vulnerability include:
- Potential information disclosure by copying uninitialized areas of memory into
an IPP string value.
- Potential Denial of Service by supplying/using invalid string values when
strict validation has been disabled by the system administrator.
This change ensures that:
1. The language identifier does not extend beyond the end of the IPP value.
2. The length of the name/text string is within the IPP value.
3. The name/text string is within the IPP value.
diff --git a/cups/ipp.c b/cups/ipp.c
index 3d529346c..adbb26fba 100644
--- a/cups/ipp.c
+++ b/cups/ipp.c
@@ -2866,7 +2866,8 @@ ippReadIO(void *src, /* I - Data source */
unsigned char *buffer, /* Data buffer */
string[IPP_MAX_TEXT],
/* Small string buffer */
- *bufptr; /* Pointer into buffer */
+ *bufptr, /* Pointer into buffer */
+ *bufend; /* End of buffer */
ipp_attribute_t *attr; /* Current attribute */
ipp_tag_t tag; /* Current tag */
ipp_tag_t value_tag; /* Current value tag */
@@ -3441,6 +3442,7 @@ ippReadIO(void *src, /* I - Data source */
}
bufptr = buffer;
+ bufend = buffer + n;
/*
* text-with-language and name-with-language are composite
@@ -3454,7 +3456,7 @@ ippReadIO(void *src, /* I - Data source */
n = (bufptr[0] << 8) | bufptr[1];
- if ((bufptr + 2 + n) >= (buffer + IPP_BUF_SIZE) || n >= (int)sizeof(string))
+ if ((bufptr + 2 + n + 2) > bufend || n >= (int)sizeof(string))
{
_cupsSetError(IPP_STATUS_ERROR_INTERNAL,
_("IPP language length overflows value."), 1);
@@ -3481,7 +3483,7 @@ ippReadIO(void *src, /* I - Data source */
bufptr += 2 + n;
n = (bufptr[0] << 8) | bufptr[1];
- if ((bufptr + 2 + n) >= (buffer + IPP_BUF_SIZE))
+ if ((bufptr + 2 + n) > bufend)
{
_cupsSetError(IPP_STATUS_ERROR_INTERNAL,
_("IPP string length overflows value."), 1);