Blame SOURCES/0001-Multiple-security-disclosure-issues.patch

a1b41d
From 2c030c7a06e0c2b8227c7e85f5c58dfb339731d0 Mon Sep 17 00:00:00 2001
a1b41d
From: Michael R Sweet <michael.r.sweet@gmail.com>
a1b41d
Date: Thu, 15 Aug 2019 14:06:47 -0400
a1b41d
Subject: [PATCH] Multiple security/disclosure issues:
a1b41d
a1b41d
- CVE-2019-8696 and CVE-2019-8675: Fixed SNMP buffer overflows (rdar://51685251)
a1b41d
- Fixed IPP buffer overflow (rdar://50035411)
a1b41d
- Fixed memory disclosure issue in the scheduler (rdar://51373853)
a1b41d
- Fixed DoS issues in the scheduler (rdar://51373929)
a1b41d
a1b41d
diff --git a/cups/http.c b/cups/http.c
a1b41d
index 266a15791..fbb1bf13c 100644
a1b41d
--- a/cups/http.c
a1b41d
+++ b/cups/http.c
a1b41d
@@ -1860,7 +1860,7 @@ httpPrintf(http_t     *http,		/* I - HTTP connection */
a1b41d
 	   ...)				/* I - Additional args as needed */
a1b41d
 {
a1b41d
   ssize_t	bytes;			/* Number of bytes to write */
a1b41d
-  char		buf[16384];		/* Buffer for formatted string */
a1b41d
+  char		buf[65536];		/* Buffer for formatted string */
a1b41d
   va_list	ap;			/* Variable argument pointer */
a1b41d
 
a1b41d
 
a1b41d
@@ -1872,7 +1872,12 @@ httpPrintf(http_t     *http,		/* I - HTTP connection */
a1b41d
 
a1b41d
   DEBUG_printf(("3httpPrintf: (" CUPS_LLFMT " bytes) %s", CUPS_LLCAST bytes, buf));
a1b41d
 
a1b41d
-  if (http->data_encoding == HTTP_ENCODING_FIELDS)
a1b41d
+  if (bytes > (ssize_t)(sizeof(buf) - 1))
a1b41d
+  {
a1b41d
+    http->error = ENOMEM;
a1b41d
+    return (-1);
a1b41d
+  }
a1b41d
+  else if (http->data_encoding == HTTP_ENCODING_FIELDS)
a1b41d
     return ((int)httpWrite2(http, buf, (size_t)bytes));
a1b41d
   else
a1b41d
   {
a1b41d
diff --git a/cups/ipp.c b/cups/ipp.c
a1b41d
index 6fae52a00..1bd59cef1 100644
a1b41d
--- a/cups/ipp.c
a1b41d
+++ b/cups/ipp.c
a1b41d
@@ -4550,9 +4550,7 @@ ippSetValueTag(
a1b41d
         break;
a1b41d
 
a1b41d
     case IPP_TAG_NAME :
a1b41d
-        if (temp_tag != IPP_TAG_KEYWORD && temp_tag != IPP_TAG_URI &&
a1b41d
-            temp_tag != IPP_TAG_URISCHEME && temp_tag != IPP_TAG_LANGUAGE &&
a1b41d
-            temp_tag != IPP_TAG_MIMETYPE)
a1b41d
+        if (temp_tag != IPP_TAG_KEYWORD)
a1b41d
           return (0);
a1b41d
 
a1b41d
         (*attr)->value_tag = (ipp_tag_t)(IPP_TAG_NAME | ((*attr)->value_tag & IPP_TAG_CUPS_CONST));
a1b41d
@@ -4560,10 +4558,7 @@ ippSetValueTag(
a1b41d
 
a1b41d
     case IPP_TAG_NAMELANG :
a1b41d
     case IPP_TAG_TEXTLANG :
a1b41d
-        if (value_tag == IPP_TAG_NAMELANG &&
a1b41d
-            (temp_tag != IPP_TAG_NAME && temp_tag != IPP_TAG_KEYWORD &&
a1b41d
-             temp_tag != IPP_TAG_URI && temp_tag != IPP_TAG_URISCHEME &&
a1b41d
-             temp_tag != IPP_TAG_LANGUAGE && temp_tag != IPP_TAG_MIMETYPE))
a1b41d
+        if (value_tag == IPP_TAG_NAMELANG && (temp_tag != IPP_TAG_NAME && temp_tag != IPP_TAG_KEYWORD))
a1b41d
           return (0);
a1b41d
 
a1b41d
         if (value_tag == IPP_TAG_TEXTLANG && temp_tag != IPP_TAG_TEXT)
a1b41d
diff --git a/cups/snmp.c b/cups/snmp.c
a1b41d
index 5cefee454..1d9da01f2 100644
a1b41d
--- a/cups/snmp.c
a1b41d
+++ b/cups/snmp.c
a1b41d
@@ -1233,6 +1233,9 @@ asn1_get_integer(
a1b41d
   int	value;				/* Integer value */
a1b41d
 
a1b41d
 
a1b41d
+  if (*buffer >= bufend)
a1b41d
+    return (0);
a1b41d
+
a1b41d
   if (length > sizeof(int))
a1b41d
   {
a1b41d
     (*buffer) += length;
a1b41d
@@ -1259,6 +1262,9 @@ asn1_get_length(unsigned char **buffer,	/* IO - Pointer in buffer */
a1b41d
   unsigned	length;			/* Length */
a1b41d
 
a1b41d
 
a1b41d
+  if (*buffer >= bufend)
a1b41d
+    return (0);
a1b41d
+
a1b41d
   length = **buffer;
a1b41d
   (*buffer) ++;
a1b41d
 
a1b41d
@@ -1301,6 +1307,9 @@ asn1_get_oid(
a1b41d
   int		number;			/* OID number */
a1b41d
 
a1b41d
 
a1b41d
+  if (*buffer >= bufend)
a1b41d
+    return (0);
a1b41d
+
a1b41d
   valend = *buffer + length;
a1b41d
   oidptr = oid;
a1b41d
   oidend = oid + oidsize - 1;
a1b41d
@@ -1349,9 +1358,12 @@ asn1_get_packed(
a1b41d
   int	value;				/* Value */
a1b41d
 
a1b41d
 
a1b41d
+  if (*buffer >= bufend)
a1b41d
+    return (0);
a1b41d
+
a1b41d
   value = 0;
a1b41d
 
a1b41d
-  while ((**buffer & 128) && *buffer < bufend)
a1b41d
+  while (*buffer < bufend && (**buffer & 128))
a1b41d
   {
a1b41d
     value = (value << 7) | (**buffer & 127);
a1b41d
     (*buffer) ++;
a1b41d
@@ -1379,6 +1391,9 @@ asn1_get_string(
a1b41d
     char          *string,		/* I  - String buffer */
a1b41d
     size_t        strsize)		/* I  - String buffer size */
a1b41d
 {
a1b41d
+  if (*buffer >= bufend)
a1b41d
+    return (NULL);
a1b41d
+
a1b41d
   if (length > (unsigned)(bufend - *buffer))
a1b41d
     length = (unsigned)(bufend - *buffer);
a1b41d
 
a1b41d
@@ -1421,6 +1436,9 @@ asn1_get_type(unsigned char **buffer,	/* IO - Pointer in buffer */
a1b41d
   int	type;				/* Type */
a1b41d
 
a1b41d
 
a1b41d
+  if (*buffer >= bufend)
a1b41d
+    return (0);
a1b41d
+
a1b41d
   type = **buffer;
a1b41d
   (*buffer) ++;
a1b41d
 
a1b41d
diff --git a/scheduler/client.c b/scheduler/client.c
a1b41d
index 923a6e67a..f693e7c49 100644
a1b41d
--- a/scheduler/client.c
a1b41d
+++ b/scheduler/client.c
a1b41d
@@ -564,6 +564,17 @@ cupsdReadClient(cupsd_client_t *con)	/* I - Client to read from */
a1b41d
 
a1b41d
   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);
a1b41d
 
a1b41d
+  if (httpError(con->http) == EPIPE && !httpGetReady(con->http) && recv(httpGetFd(con->http), buf, 1, MSG_PEEK) < 1)
a1b41d
+  {
a1b41d
+   /*
a1b41d
+    * Connection closed...
a1b41d
+    */
a1b41d
+
a1b41d
+    cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing on EOF.");
a1b41d
+    cupsdCloseClient(con);
a1b41d
+    return;
a1b41d
+  }
a1b41d
+
a1b41d
   if (httpGetState(con->http) == HTTP_STATE_GET_SEND ||
a1b41d
       httpGetState(con->http) == HTTP_STATE_POST_SEND ||
a1b41d
       httpGetState(con->http) == HTTP_STATE_STATUS)
a1b41d
@@ -573,17 +584,6 @@ cupsdReadClient(cupsd_client_t *con)	/* I - Client to read from */
a1b41d
     * connection and we need to shut it down...
a1b41d
     */
a1b41d
 
a1b41d
-    if (!httpGetReady(con->http) && recv(httpGetFd(con->http), buf, 1, MSG_PEEK) < 1)
a1b41d
-    {
a1b41d
-     /*
a1b41d
-      * Connection closed...
a1b41d
-      */
a1b41d
-
a1b41d
-      cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing on EOF.");
a1b41d
-      cupsdCloseClient(con);
a1b41d
-      return;
a1b41d
-    }
a1b41d
-
a1b41d
     cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing on unexpected HTTP read state %s.", httpStateString(httpGetState(con->http)));
a1b41d
     cupsdCloseClient(con);
a1b41d
     return;
a1b41d
@@ -1950,6 +1950,7 @@ cupsdSendError(cupsd_client_t *con,	/* I - Connection */
a1b41d
   strlcpy(location, httpGetField(con->http, HTTP_FIELD_LOCATION), sizeof(location));
a1b41d
 
a1b41d
   httpClearFields(con->http);
a1b41d
+  httpClearCookie(con->http);
a1b41d
 
a1b41d
   httpSetField(con->http, HTTP_FIELD_LOCATION, location);
a1b41d
 
a1b41d
-- 
a1b41d
2.21.0
a1b41d