[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#635549: foomatic-filters 3.0.2-20080211-3.2+lenny1 oldstable-security upload for CVE-2011-2697



Hi again Moritz,
(CC'ing #635549 as it was mentionned there and team@s.d.o as per [0])

On Wed, 04 Jan 2012 13:04:22 +0100, Didier Raboud wrote:
(By the way, given that there is _no_ C version of foomatic-rip in
lenny's foomatic-filters, I think that lenny is not affected by
CVE-2011-2964; it is by CVE-2011-2697 though, I'll see what I can do
on that side.)

So now I have been preparing an oldstable-security upload for foomatic-filters, reportedly vulnerable to CVE-2011-2697 in its version currently in oldstable. Same as before: it was mostly a matter of cherry-picking the changes already prepared by the Ubuntu folks [1].

debdiff is attached, proposed changelog entry is below, please comment.

foomatic-filters (3.0.2-20080211-3.2+lenny1) oldstable-security; urgency=high

 * Fix CVE-2011-2697
   "foomatic-rip in foomatic-filters allows remote attackers to execute
arbitrary code via a crafted *FoomaticRIPCommandLine field in a ppd
    file."
- Patch foomatic-rip.in using debian/patches/CVE-2011-2697.patch from
     Ubuntu hardy's 3.0.2-20071204-0ubuntu2.3, itself backported from
     upstream (revision 140).

Cheers,

OdyX

[0] http://www.debian.org/security/faq#contact
[1] https://launchpad.net/ubuntu/+source/foomatic-filters/3.0.2-20071204-0ubuntu2.3 and http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/hardy/foomatic-filters/hardy-security/view/head:/debian/patches/CVE-2011-2697.patch
diff -u foomatic-filters-3.0.2-20080211/debian/changelog foomatic-filters-3.0.2-20080211/debian/changelog
--- foomatic-filters-3.0.2-20080211/debian/changelog
+++ foomatic-filters-3.0.2-20080211/debian/changelog
@@ -1,3 +1,15 @@
+foomatic-filters (3.0.2-20080211-3.2+lenny1) oldstable-security; urgency=high
+
+  * Fix CVE-2011-2697
+    "foomatic-rip in foomatic-filters allows remote attackers to execute
+     arbitrary code via a crafted *FoomaticRIPCommandLine field in  a .ppd
+     file."
+    - Patch foomatic-rip.in using debian/patches/CVE-2011-2697.patch from
+      Ubuntu hardy's 3.0.2-20071204-0ubuntu2.3, itself backported from
+      upstream (revision 140).
+
+ -- Didier Raboud <odyx@debian.org>  Wed, 04 Jan 2012 13:15:38 +0100
+
 foomatic-filters (3.0.2-20080211-3.2) unstable; urgency=low
 
   * Non-maintainer upload.
only in patch2:
unchanged:
--- foomatic-filters-3.0.2-20080211.orig/foomatic-rip.in
+++ foomatic-filters-3.0.2-20080211/foomatic-rip.in
@@ -388,10 +388,6 @@
     $spooler = 'gnulpr';
 }
 
-
-
-## Named command line options
-
 # We do not use Getopt::Long because it does not work when between the
 # option and the argument is no space ("-w80" instead of "-w 80"). This
 # happens in the command line of LPRng, but also users could type in
@@ -409,125 +405,165 @@
 my $argstr = "\x01" . 
     join("\x01", map { removeunprintables($_) } @ARGV) . "\x01";
 
-# Debug mode activated via command line
-if ($argstr =~ s/\x01--debug\x01/\x01/) {
-    $debug = 1;
-}
+my ($verbose, $quiet, $show_docs, $do_docs, $cupscolorprofile, $genpdqfile);
 
-# Command line options for verbosity
-my $verbose = ($argstr =~ s/\x01-v\x01/\x01/);
-my $quiet = ($argstr =~ s/\x01-q\x01/\x01/);
-my $show_docs = ($argstr =~ s/\x01-d\x01/\x01/);
-my $do_docs;
-my $cupscolorprofile;
-
-if ($debug) {
-    # Grotesquely unsecure; use for debugging only
-    open LOG, "> ${logfile}.log";
-    $logh = *LOG;
-
-    use IO::Handle;
-    $logh->autoflush(1);
-} elsif (($quiet) && (!$verbose)) {
-    # Quiet mode, do not log
-    open LOG, "> /dev/null";
-    $logh = *LOG;
-
-    use IO::Handle;
-    $logh->autoflush(1);
-} else {
-    # Default: log to STDERR
-    $logh=*STDERR;
-}
+## Named command line options
 
+# CUPS calls foomatic-rip only with 5 or 6 positional parameters,
+# not with named options, like for example "-p <string>". Also PPR
+# does not used named options.
+if (($spooler ne 'cups') && ($spooler ne 'ppr') && ($spooler ne 'ppr_int')) {
+
+    # Debug mode activated via command line
+    if ($argstr =~ s/\x01--debug\x01/\x01/) {
+	$debug = 1;
+    }
+
+    # Command line options for verbosity
+    $verbose = ($argstr =~ s/\x01-v\x01/\x01/);
+    $quiet = ($argstr =~ s/\x01-q\x01/\x01/);
+    $show_docs = ($argstr =~ s/\x01-d\x01/\x01/);
+
+    if ($debug) {
+	# Grotesquely unsecure; use for debugging only
+	open LOG, "> ${logfile}.log";
+	$logh = *LOG;
+
+	use IO::Handle;
+	$logh->autoflush(1);
+    } elsif (($quiet) && (!$verbose)) {
+	# Quiet mode, do not log
+	open LOG, "> /dev/null";
+	$logh = *LOG;
+
+	use IO::Handle;
+	$logh->autoflush(1);
+     } else {
+	# Default: log to STDERR
+	$logh=*STDERR;
+    }
 
 
-## Start debug logging
-if ($debug) {
-    # If we are not in debug mode, we do this later, as we must find out at
-    # first which spooler is used. When printing without spooler we
-    # suppress logging because foomatic-rip is called directly on the
-    # command line and so we avoid logging onto the console.
-    print $logh "foomatic-rip version $ripversion running...\n";
-    # Print the command line only in debug mode, Mac OS X adds very many
-    # options so that CUPS cannot handle the output of the command line
-    # in its log files. If CUPS encounters a line with more than 1024
-    # characters sent into its log files, it aborts the job with an error.
-    if (($debug) || ($spooler ne 'cups')) {
-	print $logh "called with arguments: '", join("', '",@ARGV), "'\n";
+
+    ## Start debug logging
+    if ($debug) {
+	# If we are not in debug mode, we do this later, as we must find out at
+	# first which spooler is used. When printing without spooler we
+	# suppress logging because foomatic-rip is called directly on the
+	# command line and so we avoid logging onto the console.
+	print $logh "foomatic-rip version $ripversion running...\n";
+	# Print the command line only in debug mode, Mac OS X adds very many
+	# options so that CUPS cannot handle the output of the command line
+	# in its log files. If CUPS encounters a line with more than 1024
+	# characters sent into its log files, it aborts the job with an error.
+	if (($debug) || ($spooler ne 'cups')) {
+	    print $logh "called with arguments: '", join("', '",@ARGV), "'\n";
+	}
     }
-}
 
 
 
-## Continue with named options
+    ## Continue with named options
 
-# Check for LPRng first so we do not pick up bogus ppd files by the -p option
-if ($argstr =~ s/\x01--lprng\x01/\x01/) {
-    # We have LPRng
-    $spooler = 'lprng';
-}
-# 'PRINTCAP_ENTRY' environment variable is : LPRng
-#  the :ppd=/path/to/ppdfile printcap entry should be used
-if (defined($ENV{'PRINTCAP_ENTRY'})){
+    # Check for LPRng first so we do not pick up bogus ppd files by the -p
+    # option
+    if ($argstr =~ s/\x01--lprng\x01/\x01/) {
+	# We have LPRng
+	$spooler = 'lprng';
+    }
+    # 'PRINTCAP_ENTRY' environment variable is : LPRng
+    #  the :ppd=/path/to/ppdfile printcap entry should be used
+    if (defined($ENV{'PRINTCAP_ENTRY'})){
 	$spooler = 'lprng';
 	my( @pc);
 	@pc = split( /\s*:\s*/, $ENV{'PRINTCAP_ENTRY'} );
 	shift @pc;
 	foreach (@pc) {
-		if( /^ppd=(.*)$/ or  /^ppdfile=(.*)$/ ){
-			$ppdfile = removespecialchars($1) if $1;
-		}
-	}
-} elsif ($argstr =~ s/\x01--lprng\x01/\x01/g) {
-    # We have LPRng
-    $spooler = 'lprng';
-}
+	    if( /^ppd=(.*)$/ or  /^ppdfile=(.*)$/ ){
+		$ppdfile = removespecialchars($1) if $1;
+	    }
+	}
+    } elsif ($argstr =~ s/\x01--lprng\x01/\x01/g) {
+	# We have LPRng
+	$spooler = 'lprng';
+    }
 
+    # 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 ($argstr =~ s/\x01-h(\x01|)([^\x01]+)\x01/\x01/) {
+	# We have LPD or GNUlpr
+	if (($spooler ne 'lpd') && ($spooler ne 'gnulpr') && ($spooler ne 'lprng')) {
+	    $spooler = 'lpd';
+	}
+	$jobhost = $2;
+    }
+    if ($argstr =~ s/\x01-n(\x01|)([^\x01]+)\x01/\x01/) {
+	# We have LPD or GNUlpr
+	if (($spooler ne 'lpd') && ($spooler ne 'gnulpr') && ($spooler ne 'lprng')) {
+	    $spooler = 'lpd';
+	}
+	$jobuser = $2;
+    }
+    if (($argstr =~ s/\x01-w(\x01|)\d+\x01/\x01/) ||
+	($argstr =~ s/\x01-l(\x01|)\d+\x01/\x01/) || 
+	($argstr =~ s/\x01-x(\x01|)\d+\x01/\x01/) ||
+	($argstr =~ s/\x01-y(\x01|)\d+\x01/\x01/) || 
+	($argstr =~ s/\x01-i(\x01|)\d+\x01/\x01/) ||
+	($argstr =~ s/\x01-c\x01/\x01/)) {
+	# We have LPD or GNUlpr
+	if (($spooler ne 'lpd') && ($spooler ne 'gnulpr') && ($spooler ne 'lprng')) {
+	    $spooler = 'lpd';
+	}
+    }
 
-# PPD file name given via the command line
-# allow duplicates, and use the last specified one
-while ( ($spooler ne 'lprng') and ($argstr =~ s/\x01-p(\x01|)([^\x01]+)\x01/\x01/)) {
-    $ppdfile = removeshellescapes($2);
-}
-while ($argstr =~ s/\x01--ppd(\x01|=|)([^\x01]+)\x01/\x01/) {
-    $ppdfile = removeshellescapes($2);
-}
+    # PPD file name given via the command line
+    # allow duplicates, and use the last specified one
+    if (($spooler ne 'lprng') && ($spooler ne 'lpd') && ($spooler ne 'gnulpr')){
+	while ($argstr =~ s/\x01-p(\x01|)([^\x01]+)\x01/\x01/) {
+	    $ppdfile = $2;
+	}
+	while ($argstr =~ s/\x01--ppd(\x01|=|)([^\x01]+)\x01/\x01/) {
+	    $ppdfile = $2;
+	}
+    }
 
-# 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 ($argstr =~ s/\x01-h(\x01|)([^\x01]+)\x01/\x01/) {
-    # We have LPD or GNUlpr
-    if (($spooler ne 'lpd') && ($spooler ne 'gnulpr') && ($spooler ne 'lprng')) {
-	$spooler = 'lpd';
+    # LPRng delivers the option settings via the "-Z" argument
+    if ($argstr =~ s/\x01-Z(\x01|)([^\x01]+)\x01/\x01/) {
+	my @lpopts = split(/,/, $2);
+	foreach my $opt (@lpopts) {
+	    $opt =~ s/^\s+//;
+	    $opt =~ s/\s+$//;
+	    $opt = removeshellescapes($opt);
+	    if ($opt =~ /\s+/) {
+		$opt = "\"$opt\"";
+	    }
+	    $optstr .= "$opt ";
+	}
+	# We have LPRng
+	$spooler = 'lprng';
     }
-    $jobhost = $2;
-}
-if ($argstr =~ s/\x01-n(\x01|)([^\x01]+)\x01/\x01/) {
-    # We have LPD or GNUlpr
-    if (($spooler ne 'lpd') && ($spooler ne 'gnulpr') && ($spooler ne 'lprng')) {
-	$spooler = 'lpd';
+
+    # Job title and options for stock LPD
+    if ($argstr =~ s/\x01-[jJ](\x01|)([^\x01]+)\x01/\x01/) {
+	# An LPD
+	$jobtitle = removeshellescapes($2);
+	# Classic LPD hack
+	if ($spooler eq "lpd") {
+	    $optstr .= "$jobtitle ";
+	}
     }
-    $jobuser = $2;
-}
-if (($argstr =~ s/\x01-w(\x01|)\d+\x01/\x01/) ||
-    ($argstr =~ s/\x01-l(\x01|)\d+\x01/\x01/) || 
-    ($argstr =~ s/\x01-x(\x01|)\d+\x01/\x01/) ||
-    ($argstr =~ s/\x01-y(\x01|)\d+\x01/\x01/) || 
-    ($argstr =~ s/\x01-i(\x01|)\d+\x01/\x01/) ||
-    ($argstr =~ s/\x01-c\x01/\x01/)) {
-    # We have LPD or GNUlpr
-    if (($spooler ne 'lpd') && ($spooler ne 'gnulpr') && ($spooler ne 'lprng')) {
-	$spooler = 'lpd';
+
+    # Check for CPS
+    if ($argstr =~ s/\x01--cps\x01/\x01/) {
+	# We have cps
+	$spooler = 'cps';
     }
-}
 
-# LPRng delivers the option settings via the "-Z" argument
-if ($argstr =~ s/\x01-Z(\x01|)([^\x01]+)\x01/\x01/) {
-    my @lpopts = split(/,/, $2);
-    foreach my $opt (@lpopts) {
+    # Options for spooler-less printing, CPS, or PDQ
+    while ($argstr =~ s/\x01-o(\x01|)([^\x01]+)\x01/\x01/) {
+	my $opt = $2;
 	$opt =~ s/^\s+//;
 	$opt =~ s/\s+$//;
 	$opt = removeshellescapes($opt);
@@ -535,80 +571,49 @@
 	    $opt = "\"$opt\"";
 	}
 	$optstr .= "$opt ";
+	# If we don't print as a PPR RIP or as a CPS filter, we print without
+	# spooler (we check for PDQ later)
+	if (($spooler ne 'ppr') && ($spooler ne 'cps')) {
+	    $spooler = 'direct';
+	}
     }
-    # We have LPRng
-    $spooler = 'lprng';
-}
-
-# Job title and options for stock LPD
-if ($argstr =~ s/\x01-[jJ](\x01|)([^\x01]+)\x01/\x01/) {
-    # An LPD
-    $jobtitle = removeshellescapes($2);
-    # Classic LPD hack
-    if ($spooler eq "lpd") {
-	$optstr .= "$jobtitle ";
-    }
-}
-
-# Check for CPS
-if ($argstr =~ s/\x01--cps\x01/\x01/) {
-    # We have cps
-    $spooler = 'cps';
-}
-
-# Options for spooler-less printing, CPS, or PDQ
-while ($argstr =~ s/\x01-o(\x01|)([^\x01]+)\x01/\x01/) {
-    my $opt = $2;
-    $opt =~ s/^\s+//;
-    $opt =~ s/\s+$//;
-    $opt = removeshellescapes($opt);
-    if ($opt =~ /\s+/) {
-	$opt = "\"$opt\"";
-    }
-    $optstr .= "$opt ";
-    # If we don't print as a PPR RIP or as a CPS filter, we print without
-    # spooler (we check for PDQ later)
-    if (($spooler ne 'ppr') && ($spooler ne 'cps')) {
-	$spooler = 'direct';
-    }
-}
-
-# Printer for spooler-less printing or PDQ
-if ($argstr =~ s/\x01-d(\x01|)([^\x01]+)\x01/\x01/) {
-    $printer = removeshellescapes($2);
-}
-# Printer for spooler-less printing, PDQ, or LPRng
-if ($argstr =~ s/\x01-P(\x01|)([^\x01]+)\x01/\x01/) {
-    $printer = removeshellescapes($2);
-}
 
-# Were we called from a PDQ wrapper?
-if ($argstr =~ s/\x01--pdq\x01/\x01/) {
-    # We have PDQ
-    $spooler = 'pdq';
-}
-
-# Were we called to build the PDQ driver declaration file?
-# "--appendpdq=<file>" appends the data to the <file>,
-# "--genpdq=<file>" creates/overwrites <file> for the data, and
-# "--genpdq" writes to standard output
-my $genpdqfile = "";
-if (($argstr =~ s/\x01--(gen)(raw|)pdq(\x01|=|)([^\x01]*)\x01/\x01/) ||
-    ($argstr =~ s/\x01--(append)(raw|)pdq(\x01|=|)([^\x01]+)\x01/\x01/)) {
-    # Determine output file name
-    if (!$4) {
-	$genpdqfile = ">&STDOUT";
-    } else {
-	if ($1 eq 'gen') {
-	    $genpdqfile = "> " . removeshellescapes($4);
+    # Printer for spooler-less printing or PDQ
+    if ($argstr =~ s/\x01-d(\x01|)([^\x01]+)\x01/\x01/) {
+	$printer = removeshellescapes($2);
+    }
+    # Printer for spooler-less printing, PDQ, or LPRng
+    if ($argstr =~ s/\x01-P(\x01|)([^\x01]+)\x01/\x01/) {
+	$printer = removeshellescapes($2);
+    }
+
+    # Were we called from a PDQ wrapper?
+    if ($argstr =~ s/\x01--pdq\x01/\x01/) {
+	# We have PDQ
+	$spooler = 'pdq';
+    }
+
+    # Were we called to build the PDQ driver declaration file?
+    # "--appendpdq=<file>" appends the data to the <file>,
+    # "--genpdq=<file>" creates/overwrites <file> for the data, and
+    # "--genpdq" writes to standard output
+    $genpdqfile = "";
+    if (($argstr =~ s/\x01--(gen)(raw|)pdq(\x01|=|)([^\x01]*)\x01/\x01/) ||
+	($argstr =~ s/\x01--(append)(raw|)pdq(\x01|=|)([^\x01]+)\x01/\x01/)) {
+	# Determine output file name
+	if (!$4) {
+	    $genpdqfile = ">&STDOUT";
 	} else {
-	    $genpdqfile = ">> " . removeshellescapes($4);
+	    if ($1 eq 'gen') {
+		$genpdqfile = "> " . removeshellescapes($4);
+	    } else {
+		$genpdqfile = ">> " . removeshellescapes($4);
+	    }
 	}
-    }
-    # Do we want to have a PDQ driver declaration for a raw printer?
-    if ($2 eq 'raw') {
-	my $time = time();
-	my @pdqfile =
+	# Do we want to have a PDQ driver declaration for a raw printer?
+	if ($2 eq 'raw') {
+	    my $time = time();
+	    my @pdqfile =
 "driver \"Raw-Printer-$time\" {
   # This PDQ driver declaration file was generated automatically by
   # foomatic-rip to allow raw (filter-less) printing.
@@ -623,20 +628,22 @@
     ln -s \$INPUT \$OUTPUT
   }
 }";
-	open PDQFILE, $genpdqfile or
-	    rip_die("Cannot write PDQ driver declaration file",
-		    $EXIT_PRNERR_NORETRY_BAD_SETTINGS);
-	print PDQFILE join('', @pdqfile);
-	close PDQFILE;
-	exit $EXIT_PRINTED;
+	    open PDQFILE, $genpdqfile or
+		rip_die("Cannot write PDQ driver declaration file",
+			$EXIT_PRNERR_NORETRY_BAD_SETTINGS);
+	    print PDQFILE join('', @pdqfile);
+	    close PDQFILE;
+	    exit $EXIT_PRINTED;
+	}
+	# We have PDQ
+	$spooler = 'pdq';
     }
-    # We have PDQ
-    $spooler = 'pdq';
-}
 
 
-# remove extra spacing if running as LPRng filter
-$added_lf = "" if $spooler eq 'lprng';
+    # remove extra spacing if running as LPRng filter
+    $added_lf = "" if $spooler eq 'lprng';
+
+}
 
 ## Command line arguments without name
 

Reply to: