From a1b41db03f73c9c91ab6c5643d4098f948fdcdb4 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Apr 28 2020 09:33:55 +0000 Subject: import cups-2.2.6-33.el8 --- diff --git a/SOURCES/0001-Multiple-security-disclosure-issues.patch b/SOURCES/0001-Multiple-security-disclosure-issues.patch new file mode 100644 index 0000000..88f81f9 --- /dev/null +++ b/SOURCES/0001-Multiple-security-disclosure-issues.patch @@ -0,0 +1,183 @@ +From 2c030c7a06e0c2b8227c7e85f5c58dfb339731d0 Mon Sep 17 00:00:00 2001 +From: Michael R Sweet +Date: Thu, 15 Aug 2019 14:06:47 -0400 +Subject: [PATCH] Multiple security/disclosure issues: + +- 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) + +diff --git a/cups/http.c b/cups/http.c +index 266a15791..fbb1bf13c 100644 +--- a/cups/http.c ++++ b/cups/http.c +@@ -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 + { +diff --git a/cups/ipp.c b/cups/ipp.c +index 6fae52a00..1bd59cef1 100644 +--- a/cups/ipp.c ++++ b/cups/ipp.c +@@ -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) +diff --git a/cups/snmp.c b/cups/snmp.c +index 5cefee454..1d9da01f2 100644 +--- a/cups/snmp.c ++++ b/cups/snmp.c +@@ -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) ++; + +diff --git a/scheduler/client.c b/scheduler/client.c +index 923a6e67a..f693e7c49 100644 +--- a/scheduler/client.c ++++ b/scheduler/client.c +@@ -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); + +-- +2.21.0 + diff --git a/SOURCES/cups-do-not-advertise-http-methods.patch b/SOURCES/cups-do-not-advertise-http-methods.patch new file mode 100644 index 0000000..541da15 --- /dev/null +++ b/SOURCES/cups-do-not-advertise-http-methods.patch @@ -0,0 +1,13 @@ +diff --git a/scheduler/client.c b/scheduler/client.c +index bf284e6..0382b01 100644 +--- a/scheduler/client.c ++++ b/scheduler/client.c +@@ -1011,8 +1011,6 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ + } + + httpClearFields(con->http); +- httpSetField(con->http, HTTP_FIELD_ALLOW, +- "GET, HEAD, OPTIONS, POST, PUT"); + httpSetField(con->http, HTTP_FIELD_CONTENT_LENGTH, "0"); + + if (!cupsdSendHeader(con, HTTP_STATUS_OK, NULL, CUPSD_AUTH_NONE)) diff --git a/SOURCES/cups-memory-consumption.patch b/SOURCES/cups-memory-consumption.patch new file mode 100644 index 0000000..9418f36 --- /dev/null +++ b/SOURCES/cups-memory-consumption.patch @@ -0,0 +1,1213 @@ +diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c +index 925ab80..e5f89ee 100644 +--- a/cups/ppd-cache.c ++++ b/cups/ppd-cache.c +@@ -508,24 +508,20 @@ _ppdCacheCreateWithFile( + else if (!_cups_strcasecmp(line, "Filter")) + { + if (!pc->filters) +- pc->filters = cupsArrayNew3(NULL, NULL, NULL, 0, +- (cups_acopy_func_t)_cupsStrAlloc, +- (cups_afree_func_t)_cupsStrFree); ++ pc->filters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); + + cupsArrayAdd(pc->filters, value); + } + else if (!_cups_strcasecmp(line, "PreFilter")) + { + if (!pc->prefilters) +- pc->prefilters = cupsArrayNew3(NULL, NULL, NULL, 0, +- (cups_acopy_func_t)_cupsStrAlloc, +- (cups_afree_func_t)_cupsStrFree); ++ pc->prefilters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); + + cupsArrayAdd(pc->prefilters, value); + } + else if (!_cups_strcasecmp(line, "Product")) + { +- pc->product = _cupsStrAlloc(value); ++ pc->product = strdup(value); + } + else if (!_cups_strcasecmp(line, "SingleFile")) + { +@@ -625,8 +621,8 @@ _ppdCacheCreateWithFile( + } + + map = pc->bins + pc->num_bins; +- map->pwg = _cupsStrAlloc(pwg_keyword); +- map->ppd = _cupsStrAlloc(ppd_keyword); ++ map->pwg = strdup(pwg_keyword); ++ map->ppd = strdup(ppd_keyword); + + pc->num_bins ++; + } +@@ -680,8 +676,8 @@ _ppdCacheCreateWithFile( + goto create_error; + } + +- size->map.pwg = _cupsStrAlloc(pwg_keyword); +- size->map.ppd = _cupsStrAlloc(ppd_keyword); ++ size->map.pwg = strdup(pwg_keyword); ++ size->map.ppd = strdup(ppd_keyword); + + pc->num_sizes ++; + } +@@ -709,15 +705,15 @@ _ppdCacheCreateWithFile( + + pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "max", + pc->custom_max_width, pc->custom_max_length, NULL); +- pc->custom_max_keyword = _cupsStrAlloc(pwg_keyword); ++ pc->custom_max_keyword = strdup(pwg_keyword); + + pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "min", + pc->custom_min_width, pc->custom_min_length, NULL); +- pc->custom_min_keyword = _cupsStrAlloc(pwg_keyword); ++ pc->custom_min_keyword = strdup(pwg_keyword); + } + else if (!_cups_strcasecmp(line, "SourceOption")) + { +- pc->source_option = _cupsStrAlloc(value); ++ pc->source_option = strdup(value); + } + else if (!_cups_strcasecmp(line, "NumSources")) + { +@@ -764,8 +760,8 @@ _ppdCacheCreateWithFile( + } + + map = pc->sources + pc->num_sources; +- map->pwg = _cupsStrAlloc(pwg_keyword); +- map->ppd = _cupsStrAlloc(ppd_keyword); ++ map->pwg = strdup(pwg_keyword); ++ map->ppd = strdup(ppd_keyword); + + pc->num_sources ++; + } +@@ -813,8 +809,8 @@ _ppdCacheCreateWithFile( + } + + map = pc->types + pc->num_types; +- map->pwg = _cupsStrAlloc(pwg_keyword); +- map->ppd = _cupsStrAlloc(ppd_keyword); ++ map->pwg = strdup(pwg_keyword); ++ map->ppd = strdup(ppd_keyword); + + pc->num_types ++; + } +@@ -844,13 +840,13 @@ _ppdCacheCreateWithFile( + pc->presets[print_color_mode] + print_quality); + } + else if (!_cups_strcasecmp(line, "SidesOption")) +- pc->sides_option = _cupsStrAlloc(value); ++ pc->sides_option = strdup(value); + else if (!_cups_strcasecmp(line, "Sides1Sided")) +- pc->sides_1sided = _cupsStrAlloc(value); ++ pc->sides_1sided = strdup(value); + else if (!_cups_strcasecmp(line, "Sides2SidedLong")) +- pc->sides_2sided_long = _cupsStrAlloc(value); ++ pc->sides_2sided_long = strdup(value); + else if (!_cups_strcasecmp(line, "Sides2SidedShort")) +- pc->sides_2sided_short = _cupsStrAlloc(value); ++ pc->sides_2sided_short = strdup(value); + else if (!_cups_strcasecmp(line, "Finishings")) + { + if (!pc->finishings) +@@ -871,13 +867,13 @@ _ppdCacheCreateWithFile( + else if (!_cups_strcasecmp(line, "MaxCopies")) + pc->max_copies = atoi(value); + else if (!_cups_strcasecmp(line, "ChargeInfoURI")) +- pc->charge_info_uri = _cupsStrAlloc(value); ++ pc->charge_info_uri = strdup(value); + else if (!_cups_strcasecmp(line, "JobAccountId")) + pc->account_id = !_cups_strcasecmp(value, "true"); + else if (!_cups_strcasecmp(line, "JobAccountingUserId")) + pc->accounting_user_id = !_cups_strcasecmp(value, "true"); + else if (!_cups_strcasecmp(line, "JobPassword")) +- pc->password = _cupsStrAlloc(value); ++ pc->password = strdup(value); + else if (!_cups_strcasecmp(line, "Mandatory")) + { + if (pc->mandatory) +@@ -888,9 +884,7 @@ _ppdCacheCreateWithFile( + else if (!_cups_strcasecmp(line, "SupportFile")) + { + if (!pc->support_files) +- pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0, +- (cups_acopy_func_t)_cupsStrAlloc, +- (cups_afree_func_t)_cupsStrFree); ++ pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); + + cupsArrayAdd(pc->support_files, value); + } +@@ -1130,8 +1124,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ + */ + + new_size = old_size; +- _cupsStrFree(old_size->map.ppd); +- _cupsStrFree(old_size->map.pwg); ++ free(old_size->map.ppd); ++ free(old_size->map.pwg); + } + } + +@@ -1152,8 +1146,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ + * Save this size... + */ + +- new_size->map.ppd = _cupsStrAlloc(ppd_size->name); +- new_size->map.pwg = _cupsStrAlloc(pwg_name); ++ new_size->map.ppd = strdup(ppd_size->name); ++ new_size->map.pwg = strdup(pwg_name); + new_size->width = new_width; + new_size->length = new_length; + new_size->left = new_left; +@@ -1173,14 +1167,14 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ + pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "max", + PWG_FROM_POINTS(ppd->custom_max[0]), + PWG_FROM_POINTS(ppd->custom_max[1]), NULL); +- pc->custom_max_keyword = _cupsStrAlloc(pwg_keyword); ++ pc->custom_max_keyword = strdup(pwg_keyword); + pc->custom_max_width = PWG_FROM_POINTS(ppd->custom_max[0]); + pc->custom_max_length = PWG_FROM_POINTS(ppd->custom_max[1]); + + pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "min", + PWG_FROM_POINTS(ppd->custom_min[0]), + PWG_FROM_POINTS(ppd->custom_min[1]), NULL); +- pc->custom_min_keyword = _cupsStrAlloc(pwg_keyword); ++ pc->custom_min_keyword = strdup(pwg_keyword); + pc->custom_min_width = PWG_FROM_POINTS(ppd->custom_min[0]); + pc->custom_min_length = PWG_FROM_POINTS(ppd->custom_min[1]); + +@@ -1199,7 +1193,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ + + if (input_slot) + { +- pc->source_option = _cupsStrAlloc(input_slot->keyword); ++ pc->source_option = strdup(input_slot->keyword); + + if ((pc->sources = calloc((size_t)input_slot->num_choices, sizeof(pwg_map_t))) == NULL) + { +@@ -1251,8 +1245,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ + "_"); + } + +- map->pwg = _cupsStrAlloc(pwg_name); +- map->ppd = _cupsStrAlloc(choice->choice); ++ map->pwg = strdup(pwg_name); ++ map->ppd = strdup(choice->choice); + } + } + +@@ -1315,8 +1309,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ + "_"); + } + +- map->pwg = _cupsStrAlloc(pwg_name); +- map->ppd = _cupsStrAlloc(choice->choice); ++ map->pwg = strdup(pwg_name); ++ map->ppd = strdup(choice->choice); + } + } + +@@ -1342,8 +1336,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ + { + pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword), "_"); + +- map->pwg = _cupsStrAlloc(pwg_keyword); +- map->ppd = _cupsStrAlloc(choice->choice); ++ map->pwg = strdup(pwg_keyword); ++ map->ppd = strdup(choice->choice); + } + } + +@@ -1558,7 +1552,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ + + if (duplex) + { +- pc->sides_option = _cupsStrAlloc(duplex->keyword); ++ pc->sides_option = strdup(duplex->keyword); + + for (i = duplex->num_choices, choice = duplex->choices; + i > 0; +@@ -1566,16 +1560,16 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ + { + if ((!_cups_strcasecmp(choice->choice, "None") || + !_cups_strcasecmp(choice->choice, "False")) && !pc->sides_1sided) +- pc->sides_1sided = _cupsStrAlloc(choice->choice); ++ pc->sides_1sided = strdup(choice->choice); + else if ((!_cups_strcasecmp(choice->choice, "DuplexNoTumble") || + !_cups_strcasecmp(choice->choice, "LongEdge") || + !_cups_strcasecmp(choice->choice, "Top")) && !pc->sides_2sided_long) +- pc->sides_2sided_long = _cupsStrAlloc(choice->choice); ++ pc->sides_2sided_long = strdup(choice->choice); + else if ((!_cups_strcasecmp(choice->choice, "DuplexTumble") || + !_cups_strcasecmp(choice->choice, "ShortEdge") || + !_cups_strcasecmp(choice->choice, "Bottom")) && + !pc->sides_2sided_short) +- pc->sides_2sided_short = _cupsStrAlloc(choice->choice); ++ pc->sides_2sided_short = strdup(choice->choice); + } + } + +@@ -1583,9 +1577,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ + * Copy filters and pre-filters... + */ + +- pc->filters = cupsArrayNew3(NULL, NULL, NULL, 0, +- (cups_acopy_func_t)_cupsStrAlloc, +- (cups_afree_func_t)_cupsStrFree); ++ pc->filters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); + + cupsArrayAdd(pc->filters, + "application/vnd.cups-raw application/octet-stream 0 -"); +@@ -1642,9 +1634,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ + + if ((ppd_attr = ppdFindAttr(ppd, "cupsPreFilter", NULL)) != NULL) + { +- pc->prefilters = cupsArrayNew3(NULL, NULL, NULL, 0, +- (cups_acopy_func_t)_cupsStrAlloc, +- (cups_afree_func_t)_cupsStrFree); ++ pc->prefilters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); + + do + { +@@ -1661,7 +1651,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ + */ + + if (ppd->product) +- pc->product = _cupsStrAlloc(ppd->product); ++ pc->product = strdup(ppd->product); + + /* + * Copy finishings mapping data... +@@ -1818,7 +1808,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ + */ + + if ((ppd_attr = ppdFindAttr(ppd, "cupsChargeInfoURI", NULL)) != NULL) +- pc->charge_info_uri = _cupsStrAlloc(ppd_attr->value); ++ pc->charge_info_uri = strdup(ppd_attr->value); + + if ((ppd_attr = ppdFindAttr(ppd, "cupsJobAccountId", NULL)) != NULL) + pc->account_id = !_cups_strcasecmp(ppd_attr->value, "true"); +@@ -1827,7 +1817,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ + pc->accounting_user_id = !_cups_strcasecmp(ppd_attr->value, "true"); + + if ((ppd_attr = ppdFindAttr(ppd, "cupsJobPassword", NULL)) != NULL) +- pc->password = _cupsStrAlloc(ppd_attr->value); ++ pc->password = strdup(ppd_attr->value); + + if ((ppd_attr = ppdFindAttr(ppd, "cupsMandatory", NULL)) != NULL) + pc->mandatory = _cupsArrayNewStrings(ppd_attr->value, ' '); +@@ -1836,9 +1826,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ + * Support files... + */ + +- pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0, +- (cups_acopy_func_t)_cupsStrAlloc, +- (cups_afree_func_t)_cupsStrFree); ++ pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); + + for (ppd_attr = ppdFindAttr(ppd, "cupsICCProfile", NULL); + ppd_attr; +@@ -1894,8 +1882,8 @@ _ppdCacheDestroy(_ppd_cache_t *pc) /* I - PPD cache and mapping data */ + { + for (i = pc->num_bins, map = pc->bins; i > 0; i --, map ++) + { +- _cupsStrFree(map->pwg); +- _cupsStrFree(map->ppd); ++ free(map->pwg); ++ free(map->ppd); + } + + free(pc->bins); +@@ -1905,15 +1893,14 @@ _ppdCacheDestroy(_ppd_cache_t *pc) /* I - PPD cache and mapping data */ + { + for (i = pc->num_sizes, size = pc->sizes; i > 0; i --, size ++) + { +- _cupsStrFree(size->map.pwg); +- _cupsStrFree(size->map.ppd); ++ free(size->map.pwg); ++ free(size->map.ppd); + } + + free(pc->sizes); + } + +- if (pc->source_option) +- _cupsStrFree(pc->source_option); ++ free(pc->source_option); + + if (pc->sources) + { +@@ -1930,26 +1917,23 @@ _ppdCacheDestroy(_ppd_cache_t *pc) /* I - PPD cache and mapping data */ + { + for (i = pc->num_types, map = pc->types; i > 0; i --, map ++) + { +- _cupsStrFree(map->pwg); +- _cupsStrFree(map->ppd); ++ free(map->pwg); ++ free(map->ppd); + } + + free(pc->types); + } + +- if (pc->custom_max_keyword) +- _cupsStrFree(pc->custom_max_keyword); +- +- if (pc->custom_min_keyword) +- _cupsStrFree(pc->custom_min_keyword); ++ free(pc->custom_max_keyword); ++ free(pc->custom_min_keyword); + +- _cupsStrFree(pc->product); ++ free(pc->product); + cupsArrayDelete(pc->filters); + cupsArrayDelete(pc->prefilters); + cupsArrayDelete(pc->finishings); + +- _cupsStrFree(pc->charge_info_uri); +- _cupsStrFree(pc->password); ++ free(pc->charge_info_uri); ++ free(pc->password); + + cupsArrayDelete(pc->mandatory); + +diff --git a/cups/ppd-mark.c b/cups/ppd-mark.c +index 464c09a..cb67468 100644 +--- a/cups/ppd-mark.c ++++ b/cups/ppd-mark.c +@@ -890,9 +890,9 @@ ppd_mark_option(ppd_file_t *ppd, /* I - PPD file */ + case PPD_CUSTOM_PASSWORD : + case PPD_CUSTOM_STRING : + if (cparam->current.custom_string) +- _cupsStrFree(cparam->current.custom_string); ++ free(cparam->current.custom_string); + +- cparam->current.custom_string = _cupsStrAlloc(choice + 7); ++ cparam->current.custom_string = strdup(choice + 7); + break; + } + } +@@ -967,9 +967,9 @@ ppd_mark_option(ppd_file_t *ppd, /* I - PPD file */ + case PPD_CUSTOM_PASSWORD : + case PPD_CUSTOM_STRING : + if (cparam->current.custom_string) +- _cupsStrFree(cparam->current.custom_string); ++ free(cparam->current.custom_string); + +- cparam->current.custom_string = _cupsStrRetain(val->value); ++ cparam->current.custom_string = strdup(val->value); + break; + } + } +diff --git a/cups/ppd.c b/cups/ppd.c +index 8276988..db849ac 100644 +--- a/cups/ppd.c ++++ b/cups/ppd.c +@@ -34,8 +34,6 @@ + * Definitions... + */ + +-#define ppd_free(p) if (p) free(p) /* Safe free macro */ +- + #define PPD_KEYWORD 1 /* Line contained a keyword */ + #define PPD_OPTION 2 /* Line contained an option name */ + #define PPD_TEXT 4 /* Line contained human-readable text */ +@@ -117,7 +115,6 @@ void + ppdClose(ppd_file_t *ppd) /* I - PPD file record */ + { + int i; /* Looping var */ +- ppd_emul_t *emul; /* Current emulation */ + ppd_group_t *group; /* Current group */ + char **font; /* Current font */ + ppd_attr_t **attr; /* Current attribute */ +@@ -136,28 +133,12 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ + * Free all strings at the top level... + */ + +- _cupsStrFree(ppd->lang_encoding); +- _cupsStrFree(ppd->nickname); +- if (ppd->patches) +- free(ppd->patches); +- _cupsStrFree(ppd->jcl_begin); +- _cupsStrFree(ppd->jcl_end); +- _cupsStrFree(ppd->jcl_ps); +- +- /* +- * Free any emulations... +- */ +- +- if (ppd->num_emulations > 0) +- { +- for (i = ppd->num_emulations, emul = ppd->emulations; i > 0; i --, emul ++) +- { +- _cupsStrFree(emul->start); +- _cupsStrFree(emul->stop); +- } +- +- ppd_free(ppd->emulations); +- } ++ free(ppd->lang_encoding); ++ free(ppd->nickname); ++ free(ppd->patches); ++ free(ppd->jcl_begin); ++ free(ppd->jcl_end); ++ free(ppd->jcl_ps); + + /* + * Free any UI groups, subgroups, and options... +@@ -168,7 +149,7 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ + for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) + ppd_free_group(group); + +- ppd_free(ppd->groups); ++ free(ppd->groups); + } + + cupsArrayDelete(ppd->options); +@@ -179,14 +160,14 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ + */ + + if (ppd->num_sizes > 0) +- ppd_free(ppd->sizes); ++ free(ppd->sizes); + + /* + * Free any constraints... + */ + + if (ppd->num_consts > 0) +- ppd_free(ppd->consts); ++ free(ppd->consts); + + /* + * Free any filters... +@@ -201,9 +182,9 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ + if (ppd->num_fonts > 0) + { + for (i = ppd->num_fonts, font = ppd->fonts; i > 0; i --, font ++) +- _cupsStrFree(*font); ++ free(*font); + +- ppd_free(ppd->fonts); ++ free(ppd->fonts); + } + + /* +@@ -211,7 +192,7 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ + */ + + if (ppd->num_profiles > 0) +- ppd_free(ppd->profiles); ++ free(ppd->profiles); + + /* + * Free any attributes... +@@ -221,11 +202,11 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ + { + for (i = ppd->num_attrs, attr = ppd->attrs; i > 0; i --, attr ++) + { +- _cupsStrFree((*attr)->value); +- ppd_free(*attr); ++ free((*attr)->value); ++ free(*attr); + } + +- ppd_free(ppd->attrs); ++ free(ppd->attrs); + } + + cupsArrayDelete(ppd->sorted_attrs); +@@ -247,7 +228,7 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ + case PPD_CUSTOM_PASSCODE : + case PPD_CUSTOM_PASSWORD : + case PPD_CUSTOM_STRING : +- _cupsStrFree(cparam->current.custom_string); ++ free(cparam->current.custom_string); + break; + + default : +@@ -295,7 +276,7 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ + * Free the whole record... + */ + +- ppd_free(ppd); ++ free(ppd); + } + + +@@ -441,7 +422,6 @@ _ppdOpen( + _ppd_localization_t localization) /* I - Localization to load */ + { + int i, j, k; /* Looping vars */ +- int count; /* Temporary count */ + _ppd_line_t line; /* Line buffer */ + ppd_file_t *ppd; /* PPD file record */ + ppd_group_t *group, /* Current group */ +@@ -459,7 +439,6 @@ _ppdOpen( + /* Human-readable text from file */ + *string, /* Code/text from file */ + *sptr, /* Pointer into string */ +- *nameptr, /* Pointer into name */ + *temp, /* Temporary string pointer */ + **tempfonts; /* Temporary fonts pointer */ + float order; /* Order dependency number */ +@@ -633,16 +612,14 @@ _ppdOpen( + if (pg->ppd_status == PPD_OK) + pg->ppd_status = PPD_MISSING_PPDADOBE4; + +- _cupsStrFree(string); +- ppd_free(line.buffer); ++ free(string); ++ free(line.buffer); + + return (NULL); + } + + DEBUG_printf(("2_ppdOpen: keyword=%s, string=%p", keyword, string)); + +- _cupsStrFree(string); +- + /* + * Allocate memory for the PPD file record... + */ +@@ -651,8 +628,8 @@ _ppdOpen( + { + pg->ppd_status = PPD_ALLOC_ERROR; + +- _cupsStrFree(string); +- ppd_free(line.buffer); ++ free(string); ++ free(line.buffer); + + return (NULL); + } +@@ -735,6 +712,8 @@ _ppdOpen( + strncmp(ll, keyword, ll_len))) + { + DEBUG_printf(("2_ppdOpen: Ignoring localization: \"%s\"\n", keyword)); ++ free(string); ++ string = NULL; + continue; + } + else if (localization == _PPD_LOCALIZATION_ICC_PROFILES) +@@ -754,6 +733,8 @@ _ppdOpen( + if (i >= (int)(sizeof(color_keywords) / sizeof(color_keywords[0]))) + { + DEBUG_printf(("2_ppdOpen: Ignoring localization: \"%s\"\n", keyword)); ++ free(string); ++ string = NULL; + continue; + } + } +@@ -849,7 +830,7 @@ _ppdOpen( + * Say all PPD files are UTF-8, since we convert to UTF-8... + */ + +- ppd->lang_encoding = _cupsStrAlloc("UTF-8"); ++ ppd->lang_encoding = strdup("UTF-8"); + encoding = _ppdGetEncoding(string); + } + else if (!strcmp(keyword, "LanguageVersion")) +@@ -870,10 +851,10 @@ _ppdOpen( + + + cupsCharsetToUTF8(utf8, string, sizeof(utf8), encoding); +- ppd->nickname = _cupsStrAlloc((char *)utf8); ++ ppd->nickname = strdup((char *)utf8); + } + else +- ppd->nickname = _cupsStrAlloc(string); ++ ppd->nickname = strdup(string); + } + else if (!strcmp(keyword, "Product")) + ppd->product = string; +@@ -883,17 +864,17 @@ _ppdOpen( + ppd->ttrasterizer = string; + else if (!strcmp(keyword, "JCLBegin")) + { +- ppd->jcl_begin = _cupsStrAlloc(string); ++ ppd->jcl_begin = strdup(string); + ppd_decode(ppd->jcl_begin); /* Decode quoted string */ + } + else if (!strcmp(keyword, "JCLEnd")) + { +- ppd->jcl_end = _cupsStrAlloc(string); ++ ppd->jcl_end = strdup(string); + ppd_decode(ppd->jcl_end); /* Decode quoted string */ + } + else if (!strcmp(keyword, "JCLToPSInterpreter")) + { +- ppd->jcl_ps = _cupsStrAlloc(string); ++ ppd->jcl_ps = strdup(string); + ppd_decode(ppd->jcl_ps); /* Decode quoted string */ + } + else if (!strcmp(keyword, "AccurateScreensSupport")) +@@ -961,10 +942,10 @@ _ppdOpen( + ppd->num_filters ++; + + /* +- * Retain a copy of the filter string... ++ * Make a copy of the filter string... + */ + +- *filter = _cupsStrRetain(string); ++ *filter = strdup(string); + } + else if (!strcmp(keyword, "Throughput")) + ppd->throughput = atoi(string); +@@ -987,7 +968,7 @@ _ppdOpen( + } + + ppd->fonts = tempfonts; +- ppd->fonts[ppd->num_fonts] = _cupsStrAlloc(name); ++ ppd->fonts[ppd->num_fonts] = strdup(name); + ppd->num_fonts ++; + } + else if (!strncmp(keyword, "ParamCustom", 11)) +@@ -1152,7 +1133,7 @@ _ppdOpen( + strlcpy(choice->text, text[0] ? text : _("Custom"), + sizeof(choice->text)); + +- choice->code = _cupsStrAlloc(string); ++ choice->code = strdup(string); + + if (custom_option->section == PPD_ORDER_JCL) + ppd_decode(choice->code); +@@ -1201,59 +1182,23 @@ _ppdOpen( + else if (!strcmp(string, "Plus90")) + ppd->landscape = 90; + } +- else if (!strcmp(keyword, "Emulators") && string) ++ else if (!strcmp(keyword, "Emulators") && string && ppd->num_emulations == 0) + { +- for (count = 1, sptr = string; sptr != NULL;) +- if ((sptr = strchr(sptr, ' ')) != NULL) +- { +- count ++; +- while (*sptr == ' ') +- sptr ++; +- } +- +- ppd->num_emulations = count; +- if ((ppd->emulations = calloc((size_t)count, sizeof(ppd_emul_t))) == NULL) +- { +- pg->ppd_status = PPD_ALLOC_ERROR; +- +- goto error; +- } +- +- for (i = 0, sptr = string; i < count; i ++) +- { +- for (nameptr = ppd->emulations[i].name; +- *sptr != '\0' && *sptr != ' '; +- sptr ++) +- if (nameptr < (ppd->emulations[i].name + sizeof(ppd->emulations[i].name) - 1)) +- *nameptr++ = *sptr; +- +- *nameptr = '\0'; +- +- while (*sptr == ' ') +- sptr ++; +- } +- } +- else if (!strncmp(keyword, "StartEmulator_", 14)) +- { +- ppd_decode(string); ++ /* ++ * Issue #5562: Samsung printer drivers incorrectly use Emulators keyword ++ * to configure themselves ++ * ++ * The Emulators keyword was loaded but never used by anything in CUPS, ++ * and has no valid purpose in CUPS. The old code was removed due to a ++ * memory leak (Issue #5475), so the following (new) code supports a single ++ * name for the Emulators keyword, allowing these drivers to work until we ++ * remove PPD and driver support entirely in a future version of CUPS. ++ */ + +- for (i = 0; i < ppd->num_emulations; i ++) +- if (!strcmp(keyword + 14, ppd->emulations[i].name)) +- { +- ppd->emulations[i].start = string; +- string = NULL; +- } +- } +- else if (!strncmp(keyword, "StopEmulator_", 13)) +- { +- ppd_decode(string); ++ ppd->num_emulations = 1; ++ ppd->emulations = calloc(1, sizeof(ppd_emul_t)); + +- for (i = 0; i < ppd->num_emulations; i ++) +- if (!strcmp(keyword + 13, ppd->emulations[i].name)) +- { +- ppd->emulations[i].stop = string; +- string = NULL; +- } ++ strlcpy(ppd->emulations[0].name, string, sizeof(ppd->emulations[0].name)); + } + else if (!strcmp(keyword, "JobPatchFile")) + { +@@ -1408,7 +1353,7 @@ _ppdOpen( + + option->section = PPD_ORDER_ANY; + +- _cupsStrFree(string); ++ free(string); + string = NULL; + + /* +@@ -1436,7 +1381,7 @@ _ppdOpen( + strlcpy(choice->text, + custom_attr->text[0] ? custom_attr->text : _("Custom"), + sizeof(choice->text)); +- choice->code = _cupsStrRetain(custom_attr->value); ++ choice->code = strdup(custom_attr->value); + } + } + else if (!strcmp(keyword, "JCLOpenUI")) +@@ -1515,7 +1460,7 @@ _ppdOpen( + option->section = PPD_ORDER_JCL; + group = NULL; + +- _cupsStrFree(string); ++ free(string); + string = NULL; + + /* +@@ -1539,14 +1484,14 @@ _ppdOpen( + strlcpy(choice->text, + custom_attr->text[0] ? custom_attr->text : _("Custom"), + sizeof(choice->text)); +- choice->code = _cupsStrRetain(custom_attr->value); ++ choice->code = strdup(custom_attr->value); + } + } + else if (!strcmp(keyword, "CloseUI") || !strcmp(keyword, "JCLCloseUI")) + { + option = NULL; + +- _cupsStrFree(string); ++ free(string); + string = NULL; + } + else if (!strcmp(keyword, "OpenGroup")) +@@ -1593,14 +1538,14 @@ _ppdOpen( + if (group == NULL) + goto error; + +- _cupsStrFree(string); ++ free(string); + string = NULL; + } + else if (!strcmp(keyword, "CloseGroup")) + { + group = NULL; + +- _cupsStrFree(string); ++ free(string); + string = NULL; + } + else if (!strcmp(keyword, "OrderDependency")) +@@ -1658,7 +1603,7 @@ _ppdOpen( + option->order = order; + } + +- _cupsStrFree(string); ++ free(string); + string = NULL; + } + else if (!strncmp(keyword, "Default", 7)) +@@ -1901,7 +1846,7 @@ _ppdOpen( + * Don't add this one as an attribute... + */ + +- _cupsStrFree(string); ++ free(string); + string = NULL; + } + else if (!strcmp(keyword, "PaperDimension")) +@@ -1923,7 +1868,7 @@ _ppdOpen( + size->width = (float)_cupsStrScand(string, &sptr, loc); + size->length = (float)_cupsStrScand(sptr, NULL, loc); + +- _cupsStrFree(string); ++ free(string); + string = NULL; + } + else if (!strcmp(keyword, "ImageableArea")) +@@ -1947,7 +1892,7 @@ _ppdOpen( + size->right = (float)_cupsStrScand(sptr, &sptr, loc); + size->top = (float)_cupsStrScand(sptr, NULL, loc); + +- _cupsStrFree(string); ++ free(string); + string = NULL; + } + else if (option != NULL && +@@ -2003,7 +1948,7 @@ _ppdOpen( + (mask & (PPD_KEYWORD | PPD_STRING)) == (PPD_KEYWORD | PPD_STRING)) + ppd_add_attr(ppd, keyword, name, text, string); + else +- _cupsStrFree(string); ++ free(string); + } + + /* +@@ -2016,7 +1961,8 @@ _ppdOpen( + goto error; + } + +- ppd_free(line.buffer); ++ free(string); ++ free(line.buffer); + + /* + * Reset language preferences... +@@ -2098,8 +2044,8 @@ _ppdOpen( + + error: + +- _cupsStrFree(string); +- ppd_free(line.buffer); ++ free(string); ++ free(line.buffer); + + ppdClose(ppd); + +@@ -2537,9 +2483,9 @@ ppd_free_filters(ppd_file_t *ppd) /* I - PPD file */ + if (ppd->num_filters > 0) + { + for (i = ppd->num_filters, filter = ppd->filters; i > 0; i --, filter ++) +- _cupsStrFree(*filter); ++ free(*filter); + +- ppd_free(ppd->filters); ++ free(ppd->filters); + + ppd->num_filters = 0; + ppd->filters = NULL; +@@ -2566,7 +2512,7 @@ ppd_free_group(ppd_group_t *group) /* I - Group to free */ + i --, option ++) + ppd_free_option(option); + +- ppd_free(group->options); ++ free(group->options); + } + + if (group->num_subgroups > 0) +@@ -2576,7 +2522,7 @@ ppd_free_group(ppd_group_t *group) /* I - Group to free */ + i --, subgroup ++) + ppd_free_group(subgroup); + +- ppd_free(group->subgroups); ++ free(group->subgroups); + } + } + +@@ -2598,10 +2544,10 @@ ppd_free_option(ppd_option_t *option) /* I - Option to free */ + i > 0; + i --, choice ++) + { +- _cupsStrFree(choice->code); ++ free(choice->code); + } + +- ppd_free(option->choices); ++ free(option->choices); + } + } + +@@ -3338,7 +3284,7 @@ ppd_read(cups_file_t *fp, /* I - File to read from */ + lineptr ++; + } + +- *string = _cupsStrAlloc(lineptr); ++ *string = strdup(lineptr); + + mask |= PPD_STRING; + } +@@ -3460,7 +3406,7 @@ ppd_update_filters(ppd_file_t *ppd, /* I - PPD file */ + filter += ppd->num_filters; + ppd->num_filters ++; + +- *filter = _cupsStrAlloc(buffer); ++ *filter = strdup(buffer); + } + while ((attr = ppdFindNextAttr(ppd, "cupsFilter2", NULL)) != NULL); + +diff --git a/cups/ppd.h b/cups/ppd.h +index fb33c08..1c852c7 100644 +--- a/cups/ppd.h ++++ b/cups/ppd.h +@@ -302,8 +302,8 @@ typedef struct ppd_file_s /**** PPD File ****/ + int throughput; /* Pages per minute */ + ppd_cs_t colorspace; /* Default colorspace */ + char *patches; /* Patch commands to be sent to printer */ +- int num_emulations; /* Number of emulations supported */ +- ppd_emul_t *emulations; /* Emulations and the code to invoke them */ ++ int num_emulations; /* Number of emulations supported (no longer supported) @private@ */ ++ ppd_emul_t *emulations; /* Emulations and the code to invoke them (no longer supported) @private@ */ + char *jcl_begin; /* Start JCL commands */ + char *jcl_ps; /* Enter PostScript interpreter */ + char *jcl_end; /* End JCL commands */ +diff --git a/cups/string.c b/cups/string.c +index 0d4ed0f..8f37caf 100644 +--- a/cups/string.c ++++ b/cups/string.c +@@ -316,6 +316,13 @@ _cupsStrFree(const char *s) /* I - String to free */ + + key = (_cups_sp_item_t *)(s - offsetof(_cups_sp_item_t, str)); + ++ if ((item = (_cups_sp_item_t *)cupsArrayFind(stringpool, key)) != NULL && ++ item == key) ++ { ++ /* ++ * Found it, dereference... ++ */ ++ + #ifdef DEBUG_GUARDS + if (key->guard != _CUPS_STR_GUARD) + { +@@ -325,13 +332,6 @@ _cupsStrFree(const char *s) /* I - String to free */ + } + #endif /* DEBUG_GUARDS */ + +- if ((item = (_cups_sp_item_t *)cupsArrayFind(stringpool, key)) != NULL && +- item == key) +- { +- /* +- * Found it, dereference... +- */ +- + item->ref_count --; + + if (!item->ref_count) +diff --git a/scheduler/ipp.c b/scheduler/ipp.c +index 298b684..e0dbc4a 100644 +--- a/scheduler/ipp.c ++++ b/scheduler/ipp.c +@@ -2918,8 +2918,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */ + if (!strcmp(attr->values[i].string.text, "none")) + continue; + +- printer->reasons[printer->num_reasons] = +- _cupsStrRetain(attr->values[i].string.text); ++ printer->reasons[printer->num_reasons] = _cupsStrAlloc(attr->values[i].string.text); + printer->num_reasons ++; + + if (!strcmp(attr->values[i].string.text, "paused") && +@@ -5437,8 +5436,7 @@ copy_printer_attrs( + + if ((p2_uri = ippFindAttribute(p2->attrs, "printer-uri-supported", + IPP_TAG_URI)) != NULL) +- member_uris->values[i].string.text = +- _cupsStrRetain(p2_uri->values[0].string.text); ++ member_uris->values[i].string.text = _cupsStrAlloc(p2_uri->values[0].string.text); + else + { + httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, +diff --git a/scheduler/printers.c b/scheduler/printers.c +index 3ec16cf..f16552e 100644 +--- a/scheduler/printers.c ++++ b/scheduler/printers.c +@@ -54,8 +54,7 @@ static int compare_printers(void *first, void *second, void *data); + static void delete_printer_filters(cupsd_printer_t *p); + static void dirty_printer(cupsd_printer_t *p); + static void load_ppd(cupsd_printer_t *p); +-static ipp_t *new_media_col(pwg_size_t *size, const char *source, +- const char *type); ++static ipp_t *new_media_col(pwg_size_t *size); + static void write_xml_string(cups_file_t *fp, const char *s); + + +@@ -3873,21 +3872,19 @@ dirty_printer(cupsd_printer_t *p) /* I - Printer */ + static void + load_ppd(cupsd_printer_t *p) /* I - Printer */ + { +- int i, j, k; /* Looping vars */ ++ int i, j; /* Looping vars */ + char cache_name[1024]; /* Cache filename */ + struct stat cache_info; /* Cache file info */ + ppd_file_t *ppd; /* PPD file */ + char ppd_name[1024]; /* PPD filename */ + struct stat ppd_info; /* PPD file info */ +- int num_media; /* Number of media options */ ++ int num_media; /* Number of media values */ + ppd_size_t *size; /* Current PPD size */ + ppd_option_t *duplex, /* Duplex option */ + *output_bin, /* OutputBin option */ + *output_mode, /* OutputMode option */ + *resolution; /* (Set|JCL|)Resolution option */ +- ppd_choice_t *choice, /* Current PPD choice */ +- *input_slot, /* Current input slot */ +- *media_type; /* Current media type */ ++ ppd_choice_t *choice; /* Current PPD choice */ + ppd_attr_t *ppd_attr; /* PPD attribute */ + int xdpi, /* Horizontal resolution */ + ydpi; /* Vertical resolution */ +@@ -4147,18 +4144,7 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ + { + ipp_t *col; /* Collection value */ + +- input_slot = ppdFindMarkedChoice(ppd, "InputSlot"); +- media_type = ppdFindMarkedChoice(ppd, "MediaType"); +- col = new_media_col(pwgsize, +- input_slot ? +- _ppdCacheGetSource(p->pc, +- input_slot->choice) : +- NULL, +- media_type ? +- _ppdCacheGetType(p->pc, +- media_type->choice) : +- NULL); +- ++ col = new_media_col(pwgsize); + ippAddCollection(p->ppd_attrs, IPP_TAG_PRINTER, "media-col-default", + col); + ippDelete(col); +@@ -4354,89 +4340,19 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ + * media-col-database + */ + +- num_media = p->pc->num_sizes; +- if (p->pc->num_sources) ++ if ((attr = ippAddCollections(p->ppd_attrs, IPP_TAG_PRINTER, "media-col-database", p->pc->num_sizes, NULL)) != NULL) + { +- if (p->pc->num_types > 0) +- num_media += p->pc->num_sizes * p->pc->num_sources * +- p->pc->num_types; +- else +- num_media += p->pc->num_sizes * p->pc->num_sources; +- } +- else if (p->pc->num_types) +- num_media += p->pc->num_sizes * p->pc->num_types; ++ /* ++ * Add each page size without source or type... ++ */ + +- if ((attr = ippAddCollections(p->ppd_attrs, IPP_TAG_PRINTER, +- "media-col-database", num_media, +- NULL)) != NULL) +- { +- for (i = p->pc->num_sizes, pwgsize = p->pc->sizes, val = attr->values; +- i > 0; +- i --, pwgsize ++) ++ for (i = 0, pwgsize = p->pc->sizes; i < p->pc->num_sizes; i ++, pwgsize ++) + { +- /* +- * Start by adding the page size without source or type... +- */ ++ ipp_t *col = new_media_col(pwgsize); + +- ppdMarkOption(ppd, "PageSize", pwgsize->map.ppd); +- +- val->collection = new_media_col(pwgsize, NULL, NULL); +- val ++; +- +- /* +- * Then add the specific, supported combinations of size, source, and +- * type... +- */ +- +- if (p->pc->num_sources > 0) +- { +- for (j = p->pc->num_sources, pwgsource = p->pc->sources; +- j > 0; +- j --, pwgsource ++) +- { +- ppdMarkOption(ppd, "InputSlot", pwgsource->ppd); +- +- if (p->pc->num_types > 0) +- { +- for (k = p->pc->num_types, pwgtype = p->pc->types; +- k > 0; +- k --, pwgtype ++) +- { +- if (!ppdMarkOption(ppd, "MediaType", pwgtype->ppd)) +- { +- val->collection = new_media_col(pwgsize, pwgsource->pwg, +- pwgtype->pwg); +- val ++; +- } +- } +- } +- else if (!ppdConflicts(ppd)) +- { +- val->collection = new_media_col(pwgsize, pwgsource->pwg, NULL); +- val ++; +- } +- } +- } +- else if (p->pc->num_types > 0) +- { +- for (j = p->pc->num_types, pwgtype = p->pc->types; +- j > 0; +- j --, pwgtype ++) +- { +- if (!ppdMarkOption(ppd, "MediaType", pwgtype->ppd)) +- { +- val->collection = new_media_col(pwgsize, NULL, pwgtype->pwg); +- val ++; +- } +- } +- } ++ ippSetCollection(p->ppd_attrs, &attr, i, col); ++ ippDelete(col); + } +- +- /* +- * Update the number of media-col-database values... +- */ +- +- attr->num_values = val - attr->values; + } + } + +@@ -5134,9 +5050,7 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ + */ + + static ipp_t * /* O - Collection value */ +-new_media_col(pwg_size_t *size, /* I - media-size/margin values */ +- const char *source, /* I - media-source value */ +- const char *type) /* I - media-type value */ ++new_media_col(pwg_size_t *size) /* I - media-size/margin values */ + { + ipp_t *media_col, /* Collection value */ + *media_size; /* media-size value */ +@@ -5145,29 +5059,15 @@ new_media_col(pwg_size_t *size, /* I - media-size/margin values */ + media_col = ippNew(); + + media_size = ippNew(); +- ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, +- "x-dimension", size->width); +- ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, +- "y-dimension", size->length); ++ ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "x-dimension", size->width); ++ ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "y-dimension", size->length); + ippAddCollection(media_col, IPP_TAG_PRINTER, "media-size", media_size); + ippDelete(media_size); + +- ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, +- "media-bottom-margin", size->bottom); +- ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, +- "media-left-margin", size->left); +- ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, +- "media-right-margin", size->right); +- ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, +- "media-top-margin", size->top); +- +- if (source) +- ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-source", +- NULL, source); +- +- if (type) +- ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-type", +- NULL, type); ++ ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-bottom-margin", size->bottom); ++ ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-left-margin", size->left); ++ ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-right-margin", size->right); ++ ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-top-margin", size->top); + + return (media_col); + } diff --git a/SPECS/cups.spec b/SPECS/cups.spec index d61bd8d..e7b121a 100644 --- a/SPECS/cups.spec +++ b/SPECS/cups.spec @@ -15,7 +15,7 @@ Summary: CUPS printing system Name: cups Epoch: 1 Version: 2.2.6 -Release: 28%{?dist} +Release: 33%{?dist} License: GPLv2+ and LGPLv2 with exceptions and AML Url: http://www.cups.org/ Source0: https://github.com/apple/cups/releases/download/v%{VERSION}/cups-%{VERSION}-source.tar.gz @@ -82,6 +82,13 @@ Patch47: 0001-The-scheduler-could-crash-while-adding-an-IPP-Everyw.patch Patch48: 0001-Remove-web-log-buttons.patch # 1650233 - cups uses md5 for hashing credentials sent through tls connection Patch49: cups-fips-compliance.patch +# 1700663 - Stop advertising the HTTP methods that are supported +Patch50: cups-do-not-advertise-http-methods.patch +# 1774462, 1774463 - CVE-2019-8696, CVE-2019-8675 - buffer overflow in SNMP and IPP, +# memory disclosure and DoS in scheduler +Patch51: 0001-Multiple-security-disclosure-issues.patch +# 1775668 - cupsd eats a lot of memory when lots of queue with extensive PPDs are created +Patch52: cups-memory-consumption.patch Patch100: cups-lspp.patch @@ -307,6 +314,13 @@ Sends IPP requests to the specified URI and tests and/or displays the results. %patch48 -p1 -b .rm-webui-buttons # 1650233 - cups uses md5 for hashing credentials sent through tls connection %patch49 -p1 -b .fips-compliance +# 1700663 - Stop advertising the HTTP methods that are supported +%patch50 -p1 -b .do-not-advertise-http-methods +# 1774462, 1774463 - CVE-2019-8696, CVE-2019-8675 - buffer overflow in SNMP and IPP, +# memory disclosure and DoS in scheduler +%patch51 -p1 -b .cve-in-scheduler +# 1775668 - cupsd eats a lot of memory when lots of queue with extensive PPDs are created +%patch52 -p1 -b .memory-consumption sed -i -e '1iMaxLogSize 0' conf/cupsd.conf.in @@ -502,6 +516,8 @@ do done %endif +%{_bindir}/rm /var/cache/cups/*.data + exit 0 %post client @@ -710,6 +726,22 @@ rm -f %{cups_serverbin}/backend/smb %{_mandir}/man5/ipptoolfile.5.gz %changelog +* Fri Feb 14 2020 Zdenek Dohnal - 1:2.2.6-33 +- fix more memory leaks found by coverity in 1775668 + +* Fri Feb 14 2020 Zdenek Dohnal - 1:2.2.6-32 +- fix covscan issues raised by 1775668 + +* Thu Feb 06 2020 Zdenek Dohnal - 1:2.2.6-31 +- 1775668 - cupsd eats a lot of memory when lots of queue with extensive PPDs are created + +* Tue Nov 26 2019 Zdenek Dohnal - 1:2.2.6-30 +- 1774462 - CVE-2019-8675 - buffer overflow in SNMP and IPP, memory disclosure and DoS in scheduler +- 1774463 - CVE-2019-8696 + +* Mon Oct 07 2019 Zdenek Dohnal - 1:2.2.6-29 +- 1700663 - Stop advertising the HTTP methods that are supported + * Tue Aug 13 2019 Zdenek Dohnal - 1:2.2.6-28 - 1650233 - cups uses md5 for hashing credentials sent through tls connection