aboutsummaryrefslogtreecommitdiffstats
path: root/community/cups-filters
diff options
context:
space:
mode:
Diffstat (limited to 'community/cups-filters')
-rw-r--r--community/cups-filters/APKBUILD55
-rw-r--r--community/cups-filters/CVE-2023-24805.patch207
2 files changed, 249 insertions, 13 deletions
diff --git a/community/cups-filters/APKBUILD b/community/cups-filters/APKBUILD
index 6e57febae2e..9a3724fcde0 100644
--- a/community/cups-filters/APKBUILD
+++ b/community/cups-filters/APKBUILD
@@ -1,7 +1,7 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=cups-filters
-pkgver=1.28.9
-pkgrel=0
+pkgver=1.28.17
+pkgrel=6
pkgdesc="OpenPrinting CUPS filters and backends"
url="https://wiki.linuxfoundation.org/openprinting/cups-filters"
arch="all"
@@ -11,18 +11,41 @@ license="GPL-2.0-or-later LGPL-2.1-or-later MIT"
# foomatic-rip needs "a modern shell" in case the PPD requires some
# newer constructs; bash, ksh, and zsh are documented as working,
# and busybox ash supports most of what bash does
-# texttops/textopdf need FreeMono from ttf-freefont
+# texttops/textopdf need FreeMono from font-freefont
# for text printing to work
-depends="poppler-utils bc ttf-freefont ghostscript"
-makedepends="bash cups-dev libjpeg-turbo-dev poppler-dev zlib-dev
- libpng-dev tiff-dev lcms2-dev freetype-dev ghostscript-dev
- fontconfig-dev qpdf-dev avahi-dev dbus-dev linux-headers mupdf-tools
- coreutils ttf-dejavu"
+depends="poppler-utils bc font-freefont ghostscript"
+makedepends="
+ avahi-dev
+ bash
+ cups-dev
+ dbus-dev
+ font-dejavu
+ fontconfig-dev
+ freetype-dev
+ ghostscript-dev
+ lcms2-dev
+ libexif-dev
+ libjpeg-turbo-dev
+ libpng-dev
+ linux-headers
+ mupdf-tools
+ poppler-dev
+ qpdf-dev
+ tiff-dev
+ zlib-dev
+ "
subpackages="$pkgname-dev $pkgname-doc $pkgname-libs"
+pkggroups="lp"
source="https://github.com/OpenPrinting/cups-filters/releases/download/$pkgver/cups-filters-$pkgver.tar.xz
+ CVE-2023-24805.patch
"
+# secfixes:
+# 1.28.17-r3:
+# - CVE-2023-24805
+
build() {
+ CXXFLAGS="$CXXFLAGS -flto=auto -std=c++17" \
./configure \
--build=$CBUILD \
--host=$CHOST \
@@ -36,9 +59,11 @@ build() {
--with-shell=/bin/sh \
--without-rcdir \
--without-rclevels \
- --with-test-font-path=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf
+ --with-test-font-path=/usr/share/fonts/dejavu/DejaVuSans.ttf
# workaround parallel build issue by building libcupsfilters.la first
- make libcupsfilters.la && make libfontembed.la && make
+ make libcupsfilters.la
+ make libfontembed.la
+ make
}
check() {
@@ -50,10 +75,13 @@ package() {
#the pdf.utf-8 symlink isn't quite good enough
cd "$pkgdir"/usr/share/cups/charsets && \
ln -s pdf.utf-8.simple pdf.UTF-8
+
+ chgrp -R lp "$pkgdir"/etc/cups
}
dev() {
default_dev
+
# cupsfilters.drv needs pcl.h
install -Dm644 "$builddir"/filter/pcl.h \
"$pkgdir"/usr/share/cups/ppdc/pcl.h
@@ -61,10 +89,11 @@ dev() {
libs() {
pkgdesc="OpenPrinting CUPS filters and backends - cupsfilters and fontembed libraries"
- install -d "$subpkgdir"/usr/lib
- mv "$pkgdir"/usr/lib/lib*.so.* "$subpkgdir"/usr/lib/
+
+ amove usr/lib/lib*.so.*
}
sha512sums="
-fbdf01b0a3acd70e3bf036ca4944a8b85ab4ab95d945458e924692008a8a37bb0b1fb097c4d4b3cf6f5ad68ae06e8358659cdfc24974ee629be37b54f5c3dca1 cups-filters-1.28.9.tar.xz
+320544a48206165581adafb28dbef58f39c66bebd3641be3d180a692605349d9e6af6d464044db9f7bda17a67f4a079370d8cc880cd7873d684b2209882deb35 cups-filters-1.28.17.tar.xz
+7ca0c262c5f85236c85ca076c2739e5bfd53c873896a57d3b92943f4c08d49f131a8d804432462e13d184b8af971a8b0efe908aa0277438a0f4a94dc9aaf5796 CVE-2023-24805.patch
"
diff --git a/community/cups-filters/CVE-2023-24805.patch b/community/cups-filters/CVE-2023-24805.patch
new file mode 100644
index 00000000000..167a76dfc64
--- /dev/null
+++ b/community/cups-filters/CVE-2023-24805.patch
@@ -0,0 +1,207 @@
+Patch-Source: https://github.com/OpenPrinting/cups-filters/commit/93e60d3df358c0ae6f3dba79e1c9684657683d89
+--
+From 93e60d3df358c0ae6f3dba79e1c9684657683d89 Mon Sep 17 00:00:00 2001
+From: Till Kamppeter <till.kamppeter@gmail.com>
+Date: Wed, 17 May 2023 11:11:29 +0200
+Subject: [PATCH] beh backend: Use execv() instead of system() - CVE-2023-24805
+
+With execv() command line arguments are passed as separate strings and
+not the full command line in a single string. This prevents arbitrary
+command execution by escaping the quoting of the arguments in a job
+with a forged job title.
+
+In addition, done the following fixes and improvements:
+
+- Do not allow '/' in the scheme of the URI (= backend executable
+ name), to assure that only backends inside /usr/lib/cups/backend/
+ are used.
+
+- URI must have ':', to split off scheme, otherwise error out.
+
+- Check return value of snprintf() to create call path for backend, to
+ error out on truncation of a too long scheme or on complete failure
+ due to a completely odd scheme.
+
+- Use strncat() instead of strncpy() for getting scheme from URI, the latter
+ does not require setting terminating zero byte in case of truncation.
+
+- Also exclude "." or ".." as scheme, as directories are not valid CUPS
+ backends.
+
+- Do not use fprintf() in sigterm_handler(), to not interfere with a
+ fprintf() which could be running in the main process when
+ sigterm_handler() is triggered.
+
+- Use "static volatile int" for global variable job_canceled.
+---
+ backend/beh.c | 107 +++++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 84 insertions(+), 23 deletions(-)
+
+diff --git a/backend/beh.c b/backend/beh.c
+index 225fd27d5..8d51235b1 100644
+--- a/backend/beh.c
++++ b/backend/beh.c
+@@ -22,12 +22,13 @@
+ #include "backend-private.h"
+ #include <cups/array.h>
+ #include <ctype.h>
++#include <sys/wait.h>
+
+ /*
+ * Local globals...
+ */
+
+-static int job_canceled = 0; /* Set to 1 on SIGTERM */
++static volatile int job_canceled = 0; /* Set to 1 on SIGTERM */
+
+ /*
+ * Local functions...
+@@ -213,21 +214,40 @@ call_backend(char *uri, /* I - URI of final destination */
+ char **argv, /* I - Command-line arguments */
+ char *filename) { /* I - File name of input data */
+ const char *cups_serverbin; /* Location of programs */
++ char *backend_argv[8]; /* Arguments for backend */
+ char scheme[1024], /* Scheme from URI */
+ *ptr, /* Pointer into scheme */
+- cmdline[65536]; /* Backend command line */
+- int retval;
++ backend_path[2048]; /* Backend path */
++ int pid = 0, /* Process ID of backend */
++ wait_pid, /* Process ID from wait() */
++ wait_status, /* Status from child */
++ retval = 0;
++ int bytes;
+
+ /*
+ * Build the backend command line...
+ */
+
+- strncpy(scheme, uri, sizeof(scheme) - 1);
+- if (strlen(uri) > 1023)
+- scheme[1023] = '\0';
++ scheme[0] = '\0';
++ strncat(scheme, uri, sizeof(scheme) - 1);
+ if ((ptr = strchr(scheme, ':')) != NULL)
+ *ptr = '\0';
+-
++ else {
++ fprintf(stderr,
++ "ERROR: beh: Invalid URI, no colon (':') to mark end of scheme part.\n");
++ exit (CUPS_BACKEND_FAILED);
++ }
++ if (strchr(scheme, '/')) {
++ fprintf(stderr,
++ "ERROR: beh: Invalid URI, scheme contains a slash ('/').\n");
++ exit (CUPS_BACKEND_FAILED);
++ }
++ if (!strcmp(scheme, ".") || !strcmp(scheme, "..")) {
++ fprintf(stderr,
++ "ERROR: beh: Invalid URI, scheme (\"%s\") is a directory.\n",
++ scheme);
++ exit (CUPS_BACKEND_FAILED);
++ }
+ if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
+ cups_serverbin = CUPS_SERVERBIN;
+
+@@ -235,16 +255,29 @@ call_backend(char *uri, /* I - URI of final destination */
+ fprintf(stderr,
+ "ERROR: beh: Direct output into a file not supported.\n");
+ exit (CUPS_BACKEND_FAILED);
+- } else
+- snprintf(cmdline, sizeof(cmdline),
+- "%s/backend/%s '%s' '%s' '%s' '%s' '%s' %s",
+- cups_serverbin, scheme, argv[1], argv[2], argv[3],
+- /* Apply number of copies only if beh was called with a
+- file name and not with the print data in stdin, as
+- backends should handle copies only if they are called
+- with a file name */
+- (argc == 6 ? "1" : argv[4]),
+- argv[5], filename);
++ }
++
++ backend_argv[0] = uri;
++ backend_argv[1] = argv[1];
++ backend_argv[2] = argv[2];
++ backend_argv[3] = argv[3];
++ /* Apply number of copies only if beh was called with a file name
++ and not with the print data in stdin, as backends should handle
++ copies only if they are called with a file name */
++ backend_argv[4] = (argc == 6 ? "1" : argv[4]);
++ backend_argv[5] = argv[5];
++ backend_argv[6] = filename;
++ backend_argv[7] = NULL;
++
++ bytes = snprintf(backend_path, sizeof(backend_path),
++ "%s/backend/%s", cups_serverbin, scheme);
++ if (bytes < 0 || bytes >= sizeof(backend_path))
++ {
++ fprintf(stderr,
++ "ERROR: beh: Invalid scheme (\"%s\"), could not determing backend path.\n",
++ scheme);
++ return (CUPS_BACKEND_FAILED);
++ }
+
+ /*
+ * Overwrite the device URI and run the actual backend...
+@@ -253,18 +286,44 @@ call_backend(char *uri, /* I - URI of final destination */
+ setenv("DEVICE_URI", uri, 1);
+
+ fprintf(stderr,
+- "DEBUG: beh: Executing backend command line \"%s\"...\n",
+- cmdline);
++ "DEBUG: beh: Executing backend command line \"%s '%s' '%s' '%s' '%s' '%s' %s\"...\n",
++ backend_path, backend_argv[1], backend_argv[2], backend_argv[3],
++ backend_argv[4], backend_argv[5], backend_argv[6]);
+ fprintf(stderr,
+ "DEBUG: beh: Using device URI: %s\n",
+ uri);
+
+- retval = system(cmdline) >> 8;
++ if ((pid = fork()) == 0) {
++ /*
++ * Child comes here...
++ */
++
++ /* Run the backend */
++ execv(backend_path, backend_argv);
+
+- if (retval == -1)
+ fprintf(stderr, "ERROR: Unable to execute backend command line: %s\n",
+ strerror(errno));
+
++ exit(1);
++ } else if (pid < 0) {
++ /*
++ * Unable to fork!
++ */
++
++ return (CUPS_BACKEND_FAILED);
++ }
++
++ while ((wait_pid = wait(&wait_status)) < 0 && errno == EINTR);
++
++ if (wait_pid >= 0 && wait_status) {
++ if (WIFEXITED(wait_status))
++ retval = WEXITSTATUS(wait_status);
++ else if (WTERMSIG(wait_status) != SIGTERM)
++ retval = WTERMSIG(wait_status);
++ else
++ retval = 0;
++ }
++
+ return (retval);
+ }
+
+@@ -277,8 +336,10 @@ static void
+ sigterm_handler(int sig) { /* I - Signal number (unused) */
+ (void)sig;
+
+- fprintf(stderr,
+- "DEBUG: beh: Job canceled.\n");
++ const char * const msg = "DEBUG: beh: Job canceled.\n";
++ /* The if() is to eliminate the return value and silence the warning
++ about an unused return value. */
++ if (write(2, msg, strlen(msg)));
+
+ if (job_canceled)
+ _exit(CUPS_BACKEND_OK);