From fa2d942611ac59dc0478f412e68533f3297f64ec Mon Sep 17 00:00:00 2001 From: Didier Raboud Date: Wed, 4 Jan 2012 11:28:18 +0100 Subject: Add patch to fix CVE-2011-2964. "foomaticrip.c in foomatic-rip in foomatic-filters allows remote attackers to execute arbitrary code via a crafted *FoomaticRIPCommandLine field in a .ppd file." - Import debian/patches/CVE-2011-2964.patch from Ubuntu maverick's 4.0.5-0ubuntu3.1 - Enhance its DEP-3 headers. --- debian/patches/CVE-2011-2964.patch | 224 +++++++++++++++++++++++++++++++++++++ debian/patches/series | 1 + 2 files changed, 225 insertions(+) create mode 100644 debian/patches/CVE-2011-2964.patch diff --git a/debian/patches/CVE-2011-2964.patch b/debian/patches/CVE-2011-2964.patch new file mode 100644 index 0000000..a009364 --- /dev/null +++ b/debian/patches/CVE-2011-2964.patch @@ -0,0 +1,224 @@ +Description: fix arbitrary code execution via crafted PPD file + . + From upstream changelog entry: + . + foomaticrip.c: SECURITY FIX: It was possible to make CUPS executing + arbitrary commands as the system user "lp" when foomatic-rip was + used as CUPS filter. Fixed by not parsing named options (like + "--ppd lj.ppd") when foomatic-rip is running as CUPS filter, as + CUPS does not supply named options to their filters. + +Author: Till Kamppeter +Acked-by: Marc Deslauriers +Origin: upstream, http://bzr.linuxfoundation.org/loggerhead/openprinting/foomatic/foomatic-filters/revision/252 +Bug-CVE: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-2964 +Last-Update: 2011-07-24 + +Index: foomatic-filters-4.0.5/foomaticrip.c +=================================================================== +--- foomatic-filters-4.0.5.orig/foomaticrip.c 2010-08-10 06:08:04.000000000 -0400 ++++ foomatic-filters-4.0.5/foomaticrip.c 2011-08-03 11:23:00.551600057 -0400 +@@ -1230,8 +1230,11 @@ + } + + /* Check for LPRng first so we do not pick up bogus ppd files by the -ppd option */ +- if (arglist_remove_flag(arglist, "--lprng")) +- spooler = SPOOLER_LPRNG; ++ if (spooler != SPOOLER_CUPS && spooler != SPOOLER_PPR && ++ spooler != SPOOLER_PPR_INT) { ++ if (arglist_remove_flag(arglist, "--lprng")) ++ spooler = SPOOLER_LPRNG; ++ } + + /* 'PRINTCAP_ENTRY' environment variable is : LPRng + the :ppd=/path/to/ppdfile printcap entry should be used */ +@@ -1253,96 +1256,104 @@ + } + } + +- /* PPD file name given via the command line +- allow duplicates, and use the last specified one */ +- if (spooler != SPOOLER_LPRNG) { +- while ((str = arglist_get_value(arglist, "-p"))) { +- strncpy(job->ppdfile, str, 256); +- arglist_remove(arglist, "-p"); ++ /* CUPS calls foomatic-rip only with 5 or 6 positional parameters, ++ not with named options, like for example "-p ". Also PPR ++ does not used named options. */ ++ if (spooler != SPOOLER_CUPS && spooler != SPOOLER_PPR && ++ spooler != SPOOLER_PPR_INT) { ++ /* Check for LPD/GNUlpr by typical options which the spooler puts onto ++ the filter's command line (options "-w": text width, "-l": text ++ length, "-i": indent, "-x", "-y": graphics size, "-c": raw printing, ++ "-n": user name, "-h": host name) */ ++ if ((str = arglist_get_value(arglist, "-h"))) { ++ if (spooler != SPOOLER_GNULPR && spooler != SPOOLER_LPRNG) ++ spooler = SPOOLER_LPD; ++ strncpy(job->host, str, 127); ++ job->host[127] = '\0'; ++ arglist_remove(arglist, "-h"); + } +- } +- while ((str = arglist_get_value(arglist, "--ppd"))) { +- strncpy(job->ppdfile, str, 256); +- arglist_remove(arglist, "--ppd"); +- } +- +- /* Check for LPD/GNUlpr by typical options which the spooler puts onto +- the filter's command line (options "-w": text width, "-l": text +- length, "-i": indent, "-x", "-y": graphics size, "-c": raw printing, +- "-n": user name, "-h": host name) */ +- if ((str = arglist_get_value(arglist, "-h"))) { +- if (spooler != SPOOLER_GNULPR && spooler != SPOOLER_LPRNG) +- spooler = SPOOLER_LPD; +- strncpy(job->host, str, 127); +- job->host[127] = '\0'; +- arglist_remove(arglist, "-h"); +- } +- if ((str = arglist_get_value(arglist, "-n"))) { +- if (spooler != SPOOLER_GNULPR && spooler != SPOOLER_LPRNG) +- spooler = SPOOLER_LPD; +- +- strncpy(job->user, str, 127); +- job->user[127] = '\0'; +- arglist_remove(arglist, "-n"); +- } +- if (arglist_remove(arglist, "-w") || +- arglist_remove(arglist, "-l") || +- arglist_remove(arglist, "-x") || +- arglist_remove(arglist, "-y") || +- arglist_remove(arglist, "-i") || +- arglist_remove_flag(arglist, "-c")) { ++ if ((str = arglist_get_value(arglist, "-n"))) { + if (spooler != SPOOLER_GNULPR && spooler != SPOOLER_LPRNG) + spooler = SPOOLER_LPD; +- } +- /* LPRng delivers the option settings via the "-Z" argument */ +- if ((str = arglist_get_value(arglist, "-Z"))) { +- spooler = SPOOLER_LPRNG; +- dstrcatf(job->optstr, "%s ", str); +- arglist_remove(arglist, "-Z"); +- } +- /* Job title and options for stock LPD */ +- if ((str = arglist_get_value(arglist, "-j")) || (str = arglist_get_value(arglist, "-J"))) { +- strncpy_omit(job->title, str, 128, omit_shellescapes); +- if (spooler == SPOOLER_LPD) +- dstrcatf(job->optstr, "%s ", job->title); +- if (!arglist_remove(arglist, "-j")) +- arglist_remove(arglist, "-J"); +- } +- /* Check for CPS */ +- if (arglist_remove_flag(arglist, "--cps") > 0) +- spooler = SPOOLER_CPS; +- +- /* Options for spooler-less printing, CPS, or PDQ */ +- while ((str = arglist_get_value(arglist, "-o"))) { +- strncpy_omit(tmp, str, 1024, omit_shellescapes); +- dstrcatf(job->optstr, "%s ", tmp); +- arglist_remove(arglist, "-o"); +- /* If we don't print as PPR RIP or as CPS filter, we print +- without spooler (we check for PDQ later) */ +- if (spooler != SPOOLER_PPR && spooler != SPOOLER_CPS) +- spooler = SPOOLER_DIRECT; +- } + +- /* Printer for spooler-less printing or PDQ */ +- if ((str = arglist_get_value(arglist, "-d"))) { +- strncpy_omit(job->printer, str, 256, omit_shellescapes); +- arglist_remove(arglist, "-d"); +- } ++ strncpy(job->user, str, 127); ++ job->user[127] = '\0'; ++ arglist_remove(arglist, "-n"); ++ } ++ if (arglist_remove(arglist, "-w") || ++ arglist_remove(arglist, "-l") || ++ arglist_remove(arglist, "-x") || ++ arglist_remove(arglist, "-y") || ++ arglist_remove(arglist, "-i") || ++ arglist_remove_flag(arglist, "-c")) { ++ if (spooler != SPOOLER_GNULPR && spooler != SPOOLER_LPRNG) ++ spooler = SPOOLER_LPD; ++ } ++ /* LPRng delivers the option settings via the "-Z" argument */ ++ if ((str = arglist_get_value(arglist, "-Z"))) { ++ spooler = SPOOLER_LPRNG; ++ dstrcatf(job->optstr, "%s ", str); ++ arglist_remove(arglist, "-Z"); ++ } ++ /* Job title and options for stock LPD */ ++ if ((str = arglist_get_value(arglist, "-j")) || (str = arglist_get_value(arglist, "-J"))) { ++ strncpy_omit(job->title, str, 128, omit_shellescapes); ++ if (spooler == SPOOLER_LPD) ++ dstrcatf(job->optstr, "%s ", job->title); ++ if (!arglist_remove(arglist, "-j")) ++ arglist_remove(arglist, "-J"); ++ } + +- /* Printer for spooler-less printing, PDQ, or LPRng */ +- if ((str = arglist_get_value(arglist, "-P"))) { +- strncpy_omit(job->printer, str, 256, omit_shellescapes); +- arglist_remove(arglist, "-P"); +- } ++ /* Check for CPS */ ++ if (arglist_remove_flag(arglist, "--cps") > 0) ++ spooler = SPOOLER_CPS; ++ ++ /* PPD file name given via the command line ++ allow duplicates, and use the last specified one */ ++ if (spooler != SPOOLER_GNULPR && spooler != SPOOLER_LPRNG && ++ spooler != SPOOLER_LPD) { ++ while ((str = arglist_get_value(arglist, "-p"))) { ++ strncpy(job->ppdfile, str, 256); ++ arglist_remove(arglist, "-p"); ++ } ++ while ((str = arglist_get_value(arglist, "--ppd"))) { ++ strncpy(job->ppdfile, str, 256); ++ arglist_remove(arglist, "--ppd"); ++ } ++ } + +- /* Were we called from a PDQ wrapper? */ +- if (arglist_remove_flag(arglist, "--pdq")) +- spooler = SPOOLER_PDQ; +- +- /* Were we called to build the PDQ driver declaration file? */ +- genpdqfile = check_pdq_file(arglist); +- if (genpdqfile) +- spooler = SPOOLER_PDQ; ++ /* Options for spooler-less printing, CPS, or PDQ */ ++ while ((str = arglist_get_value(arglist, "-o"))) { ++ strncpy_omit(tmp, str, 1024, omit_shellescapes); ++ dstrcatf(job->optstr, "%s ", tmp); ++ arglist_remove(arglist, "-o"); ++ /* If we don't print as PPR RIP or as CPS filter, we print ++ without spooler (we check for PDQ later) */ ++ if (spooler != SPOOLER_PPR && spooler != SPOOLER_CPS) ++ spooler = SPOOLER_DIRECT; ++ } ++ ++ /* Printer for spooler-less printing or PDQ */ ++ if ((str = arglist_get_value(arglist, "-d"))) { ++ strncpy_omit(job->printer, str, 256, omit_shellescapes); ++ arglist_remove(arglist, "-d"); ++ } ++ ++ /* Printer for spooler-less printing, PDQ, or LPRng */ ++ if ((str = arglist_get_value(arglist, "-P"))) { ++ strncpy_omit(job->printer, str, 256, omit_shellescapes); ++ arglist_remove(arglist, "-P"); ++ } ++ ++ /* Were we called from a PDQ wrapper? */ ++ if (arglist_remove_flag(arglist, "--pdq")) ++ spooler = SPOOLER_PDQ; ++ ++ /* Were we called to build the PDQ driver declaration file? */ ++ genpdqfile = check_pdq_file(arglist); ++ if (genpdqfile) ++ spooler = SPOOLER_PDQ; ++ } + + /* spooler specific initialization */ + switch (spooler) { + diff --git a/debian/patches/series b/debian/patches/series index 07477d4..691965c 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,2 +1,3 @@ strncpy-tochar-use-isempty.patch unhtmlify-segfault.patch +CVE-2011-2964.patch -- cgit v1.2.3