diff --git a/SOURCES/0001-Fix-domain-socket-handling.patch b/SOURCES/0001-Fix-domain-socket-handling.patch new file mode 100644 index 0000000..35c9ebd --- /dev/null +++ b/SOURCES/0001-Fix-domain-socket-handling.patch @@ -0,0 +1,86 @@ +diff --git a/cups/http-addr.c b/cups/http-addr.c +index 61c86384b..e86dcb622 100644 +--- a/cups/http-addr.c ++++ b/cups/http-addr.c +@@ -198,31 +198,29 @@ httpAddrListen(http_addr_t *addr, /* I - Address to bind to */ + { + mode_t mask; /* Umask setting */ + +- /* +- * Remove any existing domain socket file... +- */ +- +- unlink(addr->un.sun_path); +- +- /* +- * Save the current umask and set it to 0 so that all users can access +- * the domain socket... +- */ +- +- mask = umask(0); +- +- /* +- * Bind the domain socket... +- */ ++ // Remove any existing domain socket file... ++ if ((status = unlink(addr->un.sun_path)) < 0) ++ { ++ DEBUG_printf(("1httpAddrListen: Unable to unlink \"%s\": %s", addr->un.sun_path, strerror(errno))); ++ if (errno == ENOENT) ++ status = 0; ++ } + +- status = bind(fd, (struct sockaddr *)addr, (socklen_t)httpAddrLength(addr)); ++ if (!status) ++ { ++ // Save the current umask and set it to 0 so that all users can access ++ // the domain socket... ++ mask = umask(0); + +- /* +- * Restore the umask and fix permissions... +- */ ++ // Bind the domain socket... ++ if ((status = bind(fd, (struct sockaddr *)addr, (socklen_t)httpAddrLength(addr))) < 0) ++ { ++ DEBUG_printf(("1httpAddrListen: Unable to bind domain socket \"%s\": %s", addr->un.sun_path, strerror(errno))); ++ } + +- umask(mask); +- chmod(addr->un.sun_path, 0140777); ++ // Restore the umask... ++ umask(mask); ++ } + } + else + #endif /* AF_LOCAL */ +diff --git a/scheduler/conf.c b/scheduler/conf.c +index bc52d2add..93de8cf77 100644 +--- a/scheduler/conf.c ++++ b/scheduler/conf.c +@@ -3055,6 +3055,25 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ + + cupsd_listener_t *lis; /* New listeners array */ + ++ /* ++ * If we are launched on-demand, do not use domain sockets from the config ++ * file. Also check that the domain socket path is not too long... ++ */ ++ ++#ifdef HAVE_ONDEMAND ++ if (*value == '/' && OnDemand) ++ { ++ if (strcmp(value, CUPS_DEFAULT_DOMAINSOCKET)) ++ cupsdLogMessage(CUPSD_LOG_INFO, "Ignoring %s address %s at line %d - only using domain socket from launchd/systemd.", line, value, linenum); ++ continue; ++ } ++#endif // HAVE_ONDEMAND ++ ++ if (*value == '/' && strlen(value) > (sizeof(addr->addr.un.sun_path) - 1)) ++ { ++ cupsdLogMessage(CUPSD_LOG_INFO, "Ignoring %s address %s at line %d - too long.", line, value, linenum); ++ continue; ++ } + + /* + * Get the address list... diff --git a/SOURCES/0001-httpAddrConnect2-Check-for-error-if-POLLHUP-is-in-va.patch b/SOURCES/0001-httpAddrConnect2-Check-for-error-if-POLLHUP-is-in-va.patch new file mode 100644 index 0000000..a280b4f --- /dev/null +++ b/SOURCES/0001-httpAddrConnect2-Check-for-error-if-POLLHUP-is-in-va.patch @@ -0,0 +1,43 @@ +diff -up cups-2.2.6/cups/http-addrlist.c.cupsgetjobs-pollhup cups-2.2.6/cups/http-addrlist.c +--- cups-2.2.6/cups/http-addrlist.c.cupsgetjobs-pollhup 2023-12-19 18:25:15.484637450 +0100 ++++ cups-2.2.6/cups/http-addrlist.c 2023-12-19 18:28:57.129163387 +0100 +@@ -313,6 +313,39 @@ httpAddrConnect2( + { + # ifdef HAVE_POLL + DEBUG_printf(("pfds[%d].revents=%x\n", i, pfds[i].revents)); ++ ++# ifdef _WIN32 ++ if (((WSAGetLastError() == WSAEINPROGRESS) && (pfds[i].revents & POLLIN) && (pfds[i].revents & POLLOUT)) || ++ ((pfds[i].revents & POLLHUP) && (pfds[i].revents & (POLLIN|POLLOUT)))) ++# else ++ if (((errno == EINPROGRESS) && (pfds[i].revents & POLLIN) && (pfds[i].revents & POLLOUT)) || ++ ((pfds[i].revents & POLLHUP) && (pfds[i].revents & (POLLIN|POLLOUT)))) ++# endif /* _WIN32 */ ++ { ++ // Some systems generate POLLIN or POLLOUT together with POLLHUP when doing ++ // asynchronous connections. The solution seems to be to use getsockopt to ++ // check the SO_ERROR value and ignore the POLLHUP if there is no error or ++ // the error is EINPROGRESS. ++ ++ int sres, /* Return value from getsockopt() - 0, or -1 if error */ ++ serr; /* Option SO_ERROR value */ ++ socklen_t slen = sizeof(serr); /* Option value size */ ++ ++ sres = getsockopt(fds[i], SOL_SOCKET, SO_ERROR, &serr, &slen); ++ ++ if (sres || serr) ++ { ++ pfds[i].revents |= POLLERR; ++# ifdef DEBUG ++ DEBUG_printf(("1httpAddrConnect2: getsockopt returned: %d with error: %s", sres, strerror(serr))); ++# endif ++ } ++ else if (pfds[i].revents && (pfds[i].revents & POLLHUP) && (pfds[i].revents & (POLLIN | POLLOUT))) ++ { ++ pfds[i].revents &= ~POLLHUP; ++ } ++ } ++ + if (pfds[i].revents && !(pfds[i].revents & (POLLERR | POLLHUP))) + # else + if (FD_ISSET(fds[i], &input_set) && !FD_ISSET(fds[i], &error_set)) diff --git a/SOURCES/0001-scheduler-conf.c-Print-to-stderr-if-we-don-t-open-cu.patch b/SOURCES/0001-scheduler-conf.c-Print-to-stderr-if-we-don-t-open-cu.patch new file mode 100644 index 0000000..0c7f8c3 --- /dev/null +++ b/SOURCES/0001-scheduler-conf.c-Print-to-stderr-if-we-don-t-open-cu.patch @@ -0,0 +1,36 @@ +From db9cecdd932e58c51d2d659f63415ad47d151717 Mon Sep 17 00:00:00 2001 +From: Zdenek Dohnal +Date: Fri, 1 Sep 2023 17:11:54 +0200 +Subject: [PATCH] scheduler/conf.c: Print to stderr if we don't open + cups-files.conf + +In case cupsd can't open the cups-files.conf, the error message is lost +if journal and syslog don't exist or work on system (usually in +containers). + +Log the error into stderr at this place to get the error message if +needed. +--- + scheduler/conf.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/scheduler/conf.c b/scheduler/conf.c +index b18535162..4fa7eb1df 100644 +--- a/scheduler/conf.c ++++ b/scheduler/conf.c +@@ -811,11 +811,7 @@ cupsdReadConfiguration(void) + cupsdLogMessage(CUPSD_LOG_INFO, "No %s, using defaults.", CupsFilesFile); + else + { +-#ifdef HAVE_SYSTEMD_SD_JOURNAL_H +- sd_journal_print(LOG_ERR, "Unable to open \"%s\" - %s", CupsFilesFile, strerror(errno)); +-#else +- syslog(LOG_LPR, "Unable to open \"%s\" - %s", CupsFilesFile, strerror(errno)); +-#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */ ++ fprintf(stderr, "Unable to read \"%s\" - %s\n", CupsFilesFile, strerror(errno)); + + return (0); + } +-- +2.41.0 + diff --git a/SOURCES/cups-check-for-listeners.patch b/SOURCES/cups-check-for-listeners.patch new file mode 100644 index 0000000..ffbe8d2 --- /dev/null +++ b/SOURCES/cups-check-for-listeners.patch @@ -0,0 +1,94 @@ +diff --git a/scheduler/conf.c b/scheduler/conf.c +index c113eb3..77ce179 100644 +--- a/scheduler/conf.c ++++ b/scheduler/conf.c +@@ -573,6 +573,18 @@ cupsdReadConfiguration(void) + + cupsdDeleteAllListeners(); + ++ /* ++ * Allocate Listeners array ++ */ ++ ++ Listeners = cupsArrayNew(NULL, NULL); ++ ++ if (!Listeners) ++ { ++ fprintf(stderr, "Unable to allocate memory for array Listeners.\n"); ++ return (0); ++ } ++ + old_remote_port = RemotePort; + RemotePort = 0; + +@@ -1080,28 +1092,6 @@ cupsdReadConfiguration(void) + } + } + +- /* +- * Check that we have at least one listen/port line; if not, report this +- * as an error and exit! +- */ +- +- if (cupsArrayCount(Listeners) == 0) +- { +- /* +- * No listeners! +- */ +- +- cupsdLogMessage(CUPSD_LOG_EMERG, +- "No valid Listen or Port lines were found in the " +- "configuration file."); +- +- /* +- * Commit suicide... +- */ +- +- cupsdEndProcess(getpid(), 0); +- } +- + /* + * Set the default locale using the language and charset... + */ +@@ -3162,17 +3152,6 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ + * Allocate another listener... + */ + +- if (!Listeners) +- Listeners = cupsArrayNew(NULL, NULL); +- +- if (!Listeners) +- { +- cupsdLogMessage(CUPSD_LOG_ERROR, +- "Unable to allocate %s at line %d - %s.", +- line, linenum, strerror(errno)); +- break; +- } +- + if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, +diff --git a/scheduler/main.c b/scheduler/main.c +index a6e2c3a..b935c52 100644 +--- a/scheduler/main.c ++++ b/scheduler/main.c +@@ -2113,6 +2113,21 @@ service_checkin(void) + service_add_listener(fd, 0); + } + #endif /* HAVE_LAUNCHD */ ++ ++ if (cupsArrayCount(Listeners) == 0) ++ { ++ /* ++ * No listeners! ++ */ ++ ++ cupsdLogMessage(CUPSD_LOG_EMERG, "No listener sockets present."); ++ ++ /* ++ * Commit suicide... ++ */ ++ ++ cupsdEndProcess(getpid(), 0); ++ } + } diff --git a/SOURCES/cups-preservejob-leak.patch b/SOURCES/cups-preservejob-leak.patch new file mode 100644 index 0000000..c1c132d --- /dev/null +++ b/SOURCES/cups-preservejob-leak.patch @@ -0,0 +1,31 @@ +diff --git a/scheduler/colorman.c b/scheduler/colorman.c +index 8af4e5c..9bfdb0c 100644 +--- a/scheduler/colorman.c ++++ b/scheduler/colorman.c +@@ -1083,7 +1083,7 @@ colord_create_profile( + + dbus_message_iter_get_basic(&args, &profile_path); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Created profile \"%s\".", profile_path); +- cupsArrayAdd(profiles, strdup(profile_path)); ++ cupsArrayAdd(profiles, profile_path); + + out: + +diff --git a/scheduler/job.c b/scheduler/job.c +index 0223bee..47d4c72 100644 +--- a/scheduler/job.c ++++ b/scheduler/job.c +@@ -1496,11 +1496,11 @@ cupsdDeleteJob(cupsd_job_t *job, /* I - Job */ + job->num_files = 0; + } + ++ unload_job(job); ++ + if (job->history) + free_job_history(job); + +- unload_job(job); +- + cupsArrayRemove(Jobs, job); + cupsArrayRemove(ActiveJobs, job); + cupsArrayRemove(PrintingJobs, job); diff --git a/SOURCES/cups-require-cups-socket.patch b/SOURCES/cups-require-cups-socket.patch new file mode 100644 index 0000000..1686dd9 --- /dev/null +++ b/SOURCES/cups-require-cups-socket.patch @@ -0,0 +1,12 @@ +diff --git a/scheduler/org.cups.cupsd.service.in b/scheduler/org.cups.cupsd.service.in +index c02412fb0..18b5e0386 100644 +--- a/scheduler/org.cups.cupsd.service.in ++++ b/scheduler/org.cups.cupsd.service.in +@@ -2,6 +2,7 @@ + Description=CUPS Scheduler + Documentation=man:cupsd(8) + After=network.target nss-user-lookup.target ++Requires=cups.socket + + [Service] + ExecStart=@sbindir@/cupsd -l diff --git a/SOURCES/cups-socket-remove-on-stop.patch b/SOURCES/cups-socket-remove-on-stop.patch new file mode 100644 index 0000000..ea532d0 --- /dev/null +++ b/SOURCES/cups-socket-remove-on-stop.patch @@ -0,0 +1,12 @@ +diff --git a/scheduler/org.cups.cupsd.socket.in b/scheduler/org.cups.cupsd.socket.in +index 613b977a6..1deee826a 100644 +--- a/scheduler/org.cups.cupsd.socket.in ++++ b/scheduler/org.cups.cupsd.socket.in +@@ -4,6 +4,7 @@ PartOf=org.cups.cupsd.service + + [Socket] + ListenStream=@CUPS_DEFAULT_DOMAINSOCKET@ ++RemoveOnStop=on + + [Install] + WantedBy=sockets.target diff --git a/SPECS/cups.spec b/SPECS/cups.spec index 7569de2..e951ce1 100644 --- a/SPECS/cups.spec +++ b/SPECS/cups.spec @@ -22,7 +22,7 @@ Summary: CUPS printing system Name: cups Epoch: 1 Version: 2.2.6 -Release: 54%{?dist} +Release: 60%{?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 @@ -164,6 +164,28 @@ Patch83: 0001-Log-result-of-httpGetHostname-BEFORE-closing-the-con.patch Patch84: 0001-cups-strlcpy-handle-zero-size.patch # CVE-2023-32360 cups: Information leak through Cups-Get-Document operation Patch85: 0001-Require-authentication-for-CUPS-Get-Document.patch +# RHEL-14933 cupsd memory leak in cupsdDeleteJob() with "PreserveJobHistory Off" +Patch86: cups-preservejob-leak.patch +# RHEL-15309 cupsd fails to open cups-files.conf and the resulting error message is lost +Patch87: 0001-scheduler-conf.c-Print-to-stderr-if-we-don-t-open-cu.patch +# RHEL-10702 cupsGetJobs fails to connect if poll() gets POLLOUT|POLLHUP in revents +Patch88: 0001-httpAddrConnect2-Check-for-error-if-POLLHUP-is-in-va.patch +# RHEL-40386 CVE-2024-35235 cups: Cupsd Listen arbitrary chmod 0140777 +# https://github.com/OpenPrinting/cups/commit/a436956 +Patch89: 0001-Fix-domain-socket-handling.patch +# RHEL-40386 CVE-2024-35235 cups: Cupsd Listen arbitrary chmod 0140777 +# https://github.com/OpenPrinting/cups/pull/31 +Patch90: cups-require-cups-socket.patch +# RHEL-40386 CVE-2024-35235 cups: Cupsd Listen arbitrary chmod 0140777 +# https://github.com/OpenPrinting/cups/commit/3448c52 +Patch91: cups-socket-remove-on-stop.patch +# RHEL-40386 CVE-2024-35235 cups: Cupsd Listen arbitrary chmod 0140777 +# https://github.com/OpenPrinting/cups/commit/7adb508 +# https://github.com/OpenPrinting/cups/commit/824f49f +# https://github.com/OpenPrinting/cups/commit/56b9728 +# https://github.com/OpenPrinting/cups/commit/74f437b +# https://github.com/OpenPrinting/cups/commit/fb0c914 +Patch92: cups-check-for-listeners.patch Patch1000: cups-lspp.patch @@ -465,6 +487,28 @@ Sends IPP requests to the specified URI and tests and/or displays the results. %patch84 -p1 -b .cve32324 # CVE-2023-32360 cups: Information leak through Cups-Get-Document operation %patch85 -p1 -b .get-document-auth +# RHEL-14933 cupsd memory leak in cupsdDeleteJob() with "PreserveJobHistory Off" +%patch86 -p1 -b .preservejob-leak +# RHEL-15309 cupsd fails to open cups-files.conf and the resulting error message is lost +%patch87 -p1 -b .message-stderr +# RHEL-10702 cupsGetJobs fails to connect if poll() gets POLLOUT|POLLHUP in revents +%patch88 -p1 -b .cupsgetjobs-pollhup +# RHEL-40386 CVE-2024-35235 cups: Cupsd Listen arbitrary chmod 0140777 +# https://github.com/OpenPrinting/cups/commit/a436956 +%patch89 -p1 -b .cve2024-35235 +# RHEL-40386 CVE-2024-35235 cups: Cupsd Listen arbitrary chmod 0140777 +# https://github.com/OpenPrinting/cups/pull/31 +%patch90 -p1 -b .cups-require-cups-socket +# RHEL-40386 CVE-2024-35235 cups: Cupsd Listen arbitrary chmod 0140777 +# https://github.com/OpenPrinting/cups/commit/3448c52 +%patch91 -p1 -b .cups-remove-on-stop +# RHEL-40386 CVE-2024-35235 cups: Cupsd Listen arbitrary chmod 0140777 +# https://github.com/OpenPrinting/cups/commit/7adb508 +# https://github.com/OpenPrinting/cups/commit/824f49f +# https://github.com/OpenPrinting/cups/commit/56b9728 +# https://github.com/OpenPrinting/cups/commit/74f437b +# https://github.com/OpenPrinting/cups/commit/fb0c914 +%patch92 -p1 -b .cups-check-for-listeners sed -i -e '1iMaxLogSize 0' conf/cupsd.conf.in @@ -891,6 +935,29 @@ rm -f %{cups_serverbin}/backend/smb %{_mandir}/man5/ipptoolfile.5.gz %changelog +* Tue Jun 18 2024 Pavol Zacik - 1:2.2.6-60 +- RHEL-40386 cups: Cupsd Listen arbitrary chmod 0140777 +- Delete the domain socket file after stopping the cups.socket service +- Fix cupsd Listener checks + +* Fri Jun 14 2024 Pavol Zacik - 1:2.2.6-59 +- RHEL-40386 cups: Cupsd Listen arbitrary chmod 0140777 +- Require cups.socket in cupsd service file + +* Mon Jun 10 2024 Pavol Zacik - 1:2.2.6-58 +- CVE-2024-35235 cups: Cupsd Listen arbitrary chmod 0140777 + +* Mon Feb 26 2024 Zdenek Dohnal - 1:2.2.6-57 +- revert RHEL-19200 - no new subpackages are needed + +* Wed Dec 20 2023 Zdenek Dohnal - 1:2.2.6-56 +- RHEL-10702 cupsGetJobs fails to connect if poll() gets POLLOUT|POLLHUP in revents +- RHEL-19200 Recommend new cups-filters subpackages with weak dep for better upgrade exp + +* Fri Nov 03 2023 Zdenek Dohnal - 1:2.2.6-55 +- RHEL-14933 cupsd memory leak in cupsdDeleteJob() with "PreserveJobHistory Off" +- RHEL-15309 cupsd fails to open cups-files.conf and the resulting error message is lost + * Tue Sep 12 2023 Zdenek Dohnal - 1:2.2.6-54 - RHEL-2612 - cups pulls an unneeded dependency on python3