]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Multiple security/disclosure issues: 5611/head
authorMichael R Sweet <michael.r.sweet@gmail.com>
Thu, 15 Aug 2019 18:06:47 +0000 (14:06 -0400)
committerMichael R Sweet <michael.r.sweet@gmail.com>
Thu, 15 Aug 2019 18:06:47 +0000 (14:06 -0400)
- CVE-2019-8696 and CVE-2019-8675: Fixed SNMP buffer overflows (rdar://51685251)
- Fixed IPP buffer overflow (rdar://50035411)
- Fixed memory disclosure issue in the scheduler (rdar://51373853)
- Fixed DoS issues in the scheduler (rdar://51373929)

CHANGES.md
cups/http.c
cups/ipp.c
cups/snmp.c
scheduler/client.c

index 8c7bfb0cdddd1115d754273925fa0ce896f86503..ffd236f90d2bb328d7462cce5b65c66ff482a8e9 100644 (file)
@@ -5,6 +5,7 @@ CHANGES - 2.3.0 - 2019-08-07
 Changes in CUPS v2.3.0
 ----------------------
 
+- CVE-2019-8696 and CVE-2019-8675: Fixed SNMP buffer overflows (rdar://51685251)
 - Documentation updates (Issue #5604)
 - Fixed a bug in the scheduler job cleanup code (Issue #5588)
 - Fixed builds when there is no TLS library (Issue #5590)
@@ -28,6 +29,9 @@ Changes in CUPS v2.3.0
 - Fixed some PPD parser issues (Issue #5623, Issue #5624)
 - The IPP parser no longer allows invalid member attributes in collections
   (Issue #5630)
+- Fixed IPP buffer overflow (rdar://50035411)
+- Fixed memory disclosure issue in the scheduler (rdar://51373853)
+- Fixed DoS issues in the scheduler (rdar://51373929)
 - Fixed an issue with unsupported "sides" values in the IPP backend
   (rdar://51775322)
 - The scheduler would restart continuously when idle and printers were not
@@ -37,6 +41,8 @@ Changes in CUPS v2.3.0
 - Fixed a memory leak in `ppdOpen`.
 
 
+
+
 Changes in CUPS v2.3rc1
 -----------------------
 
index 266a15791a9d0c641b0f616d8c343cce5fb29c6c..fbb1bf13cce520cd7438637a1661a1b8ff738c6f 100644 (file)
@@ -1860,7 +1860,7 @@ httpPrintf(http_t     *http,              /* I - HTTP connection */
           ...)                         /* I - Additional args as needed */
 {
   ssize_t      bytes;                  /* Number of bytes to write */
-  char         buf[16384];             /* Buffer for formatted string */
+  char         buf[65536];             /* Buffer for formatted string */
   va_list      ap;                     /* Variable argument pointer */
 
 
@@ -1872,7 +1872,12 @@ httpPrintf(http_t     *http,             /* I - HTTP connection */
 
   DEBUG_printf(("3httpPrintf: (" CUPS_LLFMT " bytes) %s", CUPS_LLCAST bytes, buf));
 
-  if (http->data_encoding == HTTP_ENCODING_FIELDS)
+  if (bytes > (ssize_t)(sizeof(buf) - 1))
+  {
+    http->error = ENOMEM;
+    return (-1);
+  }
+  else if (http->data_encoding == HTTP_ENCODING_FIELDS)
     return ((int)httpWrite2(http, buf, (size_t)bytes));
   else
   {
index 6fae52a0060576091ea327495a8421e8e535044e..1bd59cef112a452d2e3aae50f75ebd0997dab140 100644 (file)
@@ -4550,9 +4550,7 @@ ippSetValueTag(
         break;
 
     case IPP_TAG_NAME :
-        if (temp_tag != IPP_TAG_KEYWORD && temp_tag != IPP_TAG_URI &&
-            temp_tag != IPP_TAG_URISCHEME && temp_tag != IPP_TAG_LANGUAGE &&
-            temp_tag != IPP_TAG_MIMETYPE)
+        if (temp_tag != IPP_TAG_KEYWORD)
           return (0);
 
         (*attr)->value_tag = (ipp_tag_t)(IPP_TAG_NAME | ((*attr)->value_tag & IPP_TAG_CUPS_CONST));
@@ -4560,10 +4558,7 @@ ippSetValueTag(
 
     case IPP_TAG_NAMELANG :
     case IPP_TAG_TEXTLANG :
-        if (value_tag == IPP_TAG_NAMELANG &&
-            (temp_tag != IPP_TAG_NAME && temp_tag != IPP_TAG_KEYWORD &&
-             temp_tag != IPP_TAG_URI && temp_tag != IPP_TAG_URISCHEME &&
-             temp_tag != IPP_TAG_LANGUAGE && temp_tag != IPP_TAG_MIMETYPE))
+        if (value_tag == IPP_TAG_NAMELANG && (temp_tag != IPP_TAG_NAME && temp_tag != IPP_TAG_KEYWORD))
           return (0);
 
         if (value_tag == IPP_TAG_TEXTLANG && temp_tag != IPP_TAG_TEXT)
index 5cefee454159c8162282b47dd15a4938040c6106..1d9da01f20b9c75cb3976dc57a41c661623edddc 100644 (file)
@@ -1233,6 +1233,9 @@ asn1_get_integer(
   int  value;                          /* Integer value */
 
 
+  if (*buffer >= bufend)
+    return (0);
+
   if (length > sizeof(int))
   {
     (*buffer) += length;
@@ -1259,6 +1262,9 @@ asn1_get_length(unsigned char **buffer,   /* IO - Pointer in buffer */
   unsigned     length;                 /* Length */
 
 
+  if (*buffer >= bufend)
+    return (0);
+
   length = **buffer;
   (*buffer) ++;
 
@@ -1301,6 +1307,9 @@ asn1_get_oid(
   int          number;                 /* OID number */
 
 
+  if (*buffer >= bufend)
+    return (0);
+
   valend = *buffer + length;
   oidptr = oid;
   oidend = oid + oidsize - 1;
@@ -1349,9 +1358,12 @@ asn1_get_packed(
   int  value;                          /* Value */
 
 
+  if (*buffer >= bufend)
+    return (0);
+
   value = 0;
 
-  while ((**buffer & 128) && *buffer < bufend)
+  while (*buffer < bufend && (**buffer & 128))
   {
     value = (value << 7) | (**buffer & 127);
     (*buffer) ++;
@@ -1379,6 +1391,9 @@ asn1_get_string(
     char          *string,             /* I  - String buffer */
     size_t        strsize)             /* I  - String buffer size */
 {
+  if (*buffer >= bufend)
+    return (NULL);
+
   if (length > (unsigned)(bufend - *buffer))
     length = (unsigned)(bufend - *buffer);
 
@@ -1421,6 +1436,9 @@ asn1_get_type(unsigned char **buffer,     /* IO - Pointer in buffer */
   int  type;                           /* Type */
 
 
+  if (*buffer >= bufend)
+    return (0);
+
   type = **buffer;
   (*buffer) ++;
 
index 923a6e67a22e9b026b90f4caa29f279cb0def0ab..f693e7c4925e0dc0bb9b2e7a7bfce80e6140a6fb 100644 (file)
@@ -564,6 +564,17 @@ cupsdReadClient(cupsd_client_t *con)       /* I - Client to read from */
 
   cupsdLogClient(con, CUPSD_LOG_DEBUG2, "cupsdReadClient: error=%d, used=%d, state=%s, data_encoding=HTTP_ENCODING_%s, data_remaining=" CUPS_LLFMT ", request=%p(%s), file=%d", httpError(con->http), (int)httpGetReady(con->http), httpStateString(httpGetState(con->http)), httpIsChunked(con->http) ? "CHUNKED" : "LENGTH", CUPS_LLCAST httpGetRemaining(con->http), con->request, con->request ? ippStateString(ippGetState(con->request)) : "", con->file);
 
+  if (httpError(con->http) == EPIPE && !httpGetReady(con->http) && recv(httpGetFd(con->http), buf, 1, MSG_PEEK) < 1)
+  {
+   /*
+    * Connection closed...
+    */
+
+    cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing on EOF.");
+    cupsdCloseClient(con);
+    return;
+  }
+
   if (httpGetState(con->http) == HTTP_STATE_GET_SEND ||
       httpGetState(con->http) == HTTP_STATE_POST_SEND ||
       httpGetState(con->http) == HTTP_STATE_STATUS)
@@ -573,17 +584,6 @@ cupsdReadClient(cupsd_client_t *con)       /* I - Client to read from */
     * connection and we need to shut it down...
     */
 
-    if (!httpGetReady(con->http) && recv(httpGetFd(con->http), buf, 1, MSG_PEEK) < 1)
-    {
-     /*
-      * Connection closed...
-      */
-
-      cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing on EOF.");
-      cupsdCloseClient(con);
-      return;
-    }
-
     cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing on unexpected HTTP read state %s.", httpStateString(httpGetState(con->http)));
     cupsdCloseClient(con);
     return;
@@ -1950,6 +1950,7 @@ cupsdSendError(cupsd_client_t *con,       /* I - Connection */
   strlcpy(location, httpGetField(con->http, HTTP_FIELD_LOCATION), sizeof(location));
 
   httpClearFields(con->http);
+  httpClearCookie(con->http);
 
   httpSetField(con->http, HTTP_FIELD_LOCATION, location);