rpms/cups/F-10 cups-CVE-2009-2820.patch, NONE, 1.1 cups.spec, 1.466, 1.467

Tim Waugh twaugh at fedoraproject.org
Tue Nov 10 14:28:02 UTC 2009


Author: twaugh

Update of /cvs/pkgs/rpms/cups/F-10
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv13470

Modified Files:
	cups.spec 
Added Files:
	cups-CVE-2009-2820.patch 
Log Message:
* Tue Nov 10 2009 Tim Waugh <twaugh at redhat.com> 1:1.3.11-2
- Added fix for CVE-2009-2820 (bug #529833).


cups-CVE-2009-2820.patch:
 admin.c    |   93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 cgi.h      |    1 
 classes.c  |    1 
 help.c     |    9 +++++
 ipp-var.c  |   41 ++++++++++++++++++--------
 jobs.c     |    1 
 printers.c |    1 
 template.c |    4 +-
 var.c      |   44 ++++++++++++++++++++++------
 9 files changed, 165 insertions(+), 30 deletions(-)

--- NEW FILE cups-CVE-2009-2820.patch ---
diff -up cups-1.3.11/cgi-bin/admin.c.CVE-2009-2820 cups-1.3.11/cgi-bin/admin.c
--- cups-1.3.11/cgi-bin/admin.c.CVE-2009-2820	2009-06-18 22:42:45.000000000 +0100
+++ cups-1.3.11/cgi-bin/admin.c	2009-11-10 14:16:49.359666359 +0000
@@ -104,6 +104,7 @@ main(int  argc,				/* I - Number of comm
   */
 
   cgiSetVariable("SECTION", "admin");
+  cgiSetVariable("REFRESH_PAGE", "");
 
  /*
   * See if we have form data...
@@ -134,16 +135,61 @@ main(int  argc,				/* I - Number of comm
 
 
       if (getenv("HTTPS"))
-        snprintf(prefix, sizeof(prefix), "https://%s:%s",
-	         getenv("SERVER_NAME"), getenv("SERVER_PORT"));
+	snprintf(prefix, sizeof(prefix), "https://%s:%s",
+		 getenv("SERVER_NAME"), getenv("SERVER_PORT"));
       else
-        snprintf(prefix, sizeof(prefix), "http://%s:%s",
-	         getenv("SERVER_NAME"), getenv("SERVER_PORT"));
+	snprintf(prefix, sizeof(prefix), "http://%s:%s",
+		 getenv("SERVER_NAME"), getenv("SERVER_PORT"));
+
+      fprintf(stderr, "DEBUG: redirecting with prefix %s!\n", prefix);
 
       if ((url = cgiGetVariable("URL")) != NULL)
-        printf("Location: %s%s\n\n", prefix, url);
+      {
+	char	encoded[1024],		/* Encoded URL string */
+		*ptr;			/* Pointer into encoded string */
+
+
+	ptr = encoded;
+	if (*url != '/')
+	  *ptr++ = '/';
+
+	for (; *url && ptr < (encoded + sizeof(encoded) - 4); url ++)
+	{
+	  if (strchr("%@&+ <>#=", *url) || *url < ' ' || *url & 128)
+	  {
+	   /*
+	    * Percent-encode this character; safe because we have at least 4
+	    * bytes left in the array...
+	    */
+
+	    sprintf(ptr, "%%%02X", *url & 255);
+	    ptr += 3;
+	  }
+	  else
+	    *ptr++ = *url;
+	}
+
+	*ptr = '\0';
+
+	if (*url)
+	{
+	 /*
+	  * URL was too long, just redirect to the admin page...
+	  */
+
+	  printf("Location: %s/admin\n\n", prefix);
+	}
+	else
+	{
+	 /*
+	  * URL is OK, redirect there...
+	  */
+
+	  printf("Location: %s%s\n\n", prefix, encoded);
+	}
+      }
       else
-        printf("Location: %s/admin\n\n", prefix);
+	printf("Location: %s/admin\n\n", prefix);
     }
     else if (!strcmp(op, "start-printer"))
       do_printer_op(http, IPP_RESUME_PRINTER, cgiText(_("Start Printer")));
@@ -293,6 +339,31 @@ do_add_rss_subscription(http_t *http)	/*
     * and classes and (re)show the add page...
     */
 
+    if (cgiGetVariable("EVENT_JOB_CREATED"))
+      cgiSetVariable("EVENT_JOB_CREATED", "CHECKED");
+    if (cgiGetVariable("EVENT_JOB_COMPLETED"))
+      cgiSetVariable("EVENT_JOB_COMPLETED", "CHECKED");
+    if (cgiGetVariable("EVENT_JOB_STOPPED"))
+      cgiSetVariable("EVENT_JOB_STOPPED", "CHECKED");
+    if (cgiGetVariable("EVENT_JOB_CONFIG_CHANGED"))
+      cgiSetVariable("EVENT_JOB_CONFIG_CHANGED", "CHECKED");
+    if (cgiGetVariable("EVENT_PRINTER_STOPPED"))
+      cgiSetVariable("EVENT_PRINTER_STOPPED", "CHECKED");
+    if (cgiGetVariable("EVENT_PRINTER_ADDED"))
+      cgiSetVariable("EVENT_PRINTER_ADDED", "CHECKED");
+    if (cgiGetVariable("EVENT_PRINTER_MODIFIED"))
+      cgiSetVariable("EVENT_PRINTER_MODIFIED", "CHECKED");
+    if (cgiGetVariable("EVENT_PRINTER_DELETED"))
+      cgiSetVariable("EVENT_PRINTER_DELETED", "CHECKED");
+    if (cgiGetVariable("EVENT_SERVER_STARTED"))
+      cgiSetVariable("EVENT_SERVER_STARTED", "CHECKED");
+    if (cgiGetVariable("EVENT_SERVER_STOPPED"))
+      cgiSetVariable("EVENT_SERVER_STOPPED", "CHECKED");
+    if (cgiGetVariable("EVENT_SERVER_RESTARTED"))
+      cgiSetVariable("EVENT_SERVER_RESTARTED", "CHECKED");
+    if (cgiGetVariable("EVENT_SERVER_AUDIT"))
+      cgiSetVariable("EVENT_SERVER_AUDIT", "CHECKED");
+
     request  = ippNewRequest(CUPS_GET_PRINTERS);
     response = cupsDoRequest(http, request, "/");
 
@@ -415,6 +486,7 @@ do_am_class(http_t *http,		/* I - HTTP c
   ipp_attribute_t *attr;		/* member-uris attribute */
   char		uri[HTTP_MAX_URI];	/* Device or printer URI */
   const char	*name,			/* Pointer to class name */
+		*op,			/* Operation name */
 		*ptr;			/* Pointer to CGI variable */
   const char	*title;			/* Title of page */
   static const char * const pattrs[] =	/* Requested printer attributes */
@@ -426,6 +498,7 @@ do_am_class(http_t *http,		/* I - HTTP c
 
 
   title = cgiText(modify ? _("Modify Class") : _("Add Class"));
+  op    = cgiGetVariable("OP");
   name  = cgiGetVariable("PRINTER_NAME");
 
   if (cgiGetVariable("PRINTER_LOCATION") == NULL)
@@ -450,6 +523,12 @@ do_am_class(http_t *http,		/* I - HTTP c
     * Do the request and get back a response...
     */
 
+    cgiClearVariables();
+    if (op)
+      cgiSetVariable("OP", op);
+    if (name)
+      cgiSetVariable("PRINTER_NAME", name);
+
     if ((response = cupsDoRequest(http, request, "/")) != NULL)
     {
      /*
@@ -2336,7 +2415,9 @@ do_menu(http_t *http)			/* I - HTTP conn
   if ((val = cupsGetOption("DefaultAuthType", num_settings,
                            settings)) != NULL && !strcasecmp(val, "Negotiate"))
     cgiSetVariable("KERBEROS", "CHECKED");
+  else
 #endif /* HAVE_GSSAPI */
+  cgiSetVariable("KERBEROS", "");
 
   cupsFreeOptions(num_settings, settings);
 
diff -up cups-1.3.11/cgi-bin/cgi.h.CVE-2009-2820 cups-1.3.11/cgi-bin/cgi.h
--- cups-1.3.11/cgi-bin/cgi.h.CVE-2009-2820	2008-07-11 23:48:49.000000000 +0100
+++ cups-1.3.11/cgi-bin/cgi.h	2009-11-10 14:16:25.071790197 +0000
@@ -54,6 +54,7 @@ typedef struct cgi_file_s		/**** Uploade
 extern void		cgiAbort(const char *title, const char *stylesheet,
 			         const char *format, ...);
 extern int		cgiCheckVariables(const char *names);
+extern void		cgiClearVariables(void);
 extern void		*cgiCompileSearch(const char *query);
 extern void		cgiCopyTemplateFile(FILE *out, const char *tmpl);
 extern void		cgiCopyTemplateLang(const char *tmpl);
diff -up cups-1.3.11/cgi-bin/classes.c.CVE-2009-2820 cups-1.3.11/cgi-bin/classes.c
--- cups-1.3.11/cgi-bin/classes.c.CVE-2009-2820	2008-07-11 23:48:49.000000000 +0100
+++ cups-1.3.11/cgi-bin/classes.c	2009-11-10 14:16:25.077666626 +0000
@@ -69,6 +69,7 @@ main(int  argc,				/* I - Number of comm
   */
 
   cgiSetVariable("SECTION", "classes");
+  cgiSetVariable("REFRESH_PAGE", "");
 
  /*
   * See if we are displaying a printer or all classes...
diff -up cups-1.3.11/cgi-bin/help.c.CVE-2009-2820 cups-1.3.11/cgi-bin/help.c
--- cups-1.3.11/cgi-bin/help.c.CVE-2009-2820	2008-07-11 23:48:49.000000000 +0100
+++ cups-1.3.11/cgi-bin/help.c	2009-11-10 14:16:25.075666287 +0000
@@ -63,6 +63,7 @@ main(int  argc,				/* I - Number of comm
   */
 
   cgiSetVariable("SECTION", "help");
+  cgiSetVariable("REFRESH_PAGE", "");
 
  /*
   * Load the help index...
@@ -102,7 +103,7 @@ main(int  argc,				/* I - Number of comm
   */
 
   for (i = 0; i < argc; i ++)
-    fprintf(stderr, "argv[%d]=\"%s\"\n", i, argv[i]);
+    fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]);
 
   if ((helpfile = getenv("PATH_INFO")) != NULL)
   {
@@ -179,6 +180,12 @@ main(int  argc,				/* I - Number of comm
   topic = cgiGetVariable("TOPIC");
   si    = helpSearchIndex(hi, query, topic, helpfile);
 
+  cgiClearVariables();
+  if (query)
+    cgiSetVariable("QUERY", query);
+  if (topic)
+    cgiSetVariable("TOPIC", topic);
+
   fprintf(stderr, "DEBUG: query=\"%s\", topic=\"%s\"\n",
           query ? query : "(null)", topic ? topic : "(null)");
 
diff -up cups-1.3.11/cgi-bin/ipp-var.c.CVE-2009-2820 cups-1.3.11/cgi-bin/ipp-var.c
--- cups-1.3.11/cgi-bin/ipp-var.c.CVE-2009-2820	2009-03-05 18:44:14.000000000 +0000
+++ cups-1.3.11/cgi-bin/ipp-var.c	2009-11-10 14:16:25.073666611 +0000
@@ -1220,7 +1220,9 @@ cgiShowJobs(http_t     *http,		/* I - Co
   int			ascending,	/* Order of jobs (0 = descending) */
 			first,		/* First job to show */
 			count;		/* Number of jobs */
-  const char		*var;		/* Form variable */
+  const char		*var,		/* Form variable */
+			*query,		/* Query string */
+			*section;	/* Section in web interface */
   void			*search;	/* Search data */
   char			url[1024],	/* URL for prev/next/this */
 			*urlptr,	/* Position in URL */
@@ -1265,10 +1267,13 @@ cgiShowJobs(http_t     *http,		/* I - Co
     * Get a list of matching job objects.
     */
 
-    if ((var = cgiGetVariable("QUERY")) != NULL)
-      search = cgiCompileSearch(var);
+    if ((query = cgiGetVariable("QUERY")) != NULL)
+      search = cgiCompileSearch(query);
     else
+    {
+      query  = NULL;
       search = NULL;
+    }
 
     jobs  = cgiGetIPPObjects(response, search);
     count = cupsArrayCount(jobs);
@@ -1293,16 +1298,27 @@ cgiShowJobs(http_t     *http,		/* I - Co
     if (first < 0)
       first = 0;
 
-    sprintf(url, "%d", count);
-    cgiSetVariable("TOTAL", url);
-
     if ((var = cgiGetVariable("ORDER")) != NULL)
       ascending = !strcasecmp(var, "asc");
     else
-    {
       ascending = !which_jobs || !strcasecmp(which_jobs, "not-completed");
-      cgiSetVariable("ORDER", ascending ? "asc" : "dec");
-    }
+
+    section = cgiGetVariable("SECTION");
+
+    cgiClearVariables();
+
+    if (query)
+      cgiSetVariable("QUERY", query);
+
+    cgiSetVariable("ORDER", ascending ? "asc" : "dec");
+
+    cgiSetVariable("SECTION", section);
+
+    sprintf(url, "%d", count);
+    cgiSetVariable("TOTAL", url);
+
+    if (which_jobs)
+      cgiSetVariable("WHICH_JOBS", which_jobs);
 
     if (ascending)
     {
@@ -1325,11 +1341,10 @@ cgiShowJobs(http_t     *http,		/* I - Co
 
     urlend = url + sizeof(url);
 
-    if ((var = cgiGetVariable("QUERY")) != NULL)
+    if (query != NULL)
     {
       if (dest)
-        snprintf(url, sizeof(url), "/%s/%s?QUERY=", cgiGetVariable("SECTION"),
-	         dest);
+        snprintf(url, sizeof(url), "/%s/%s?QUERY=", section, dest);
       else
         strlcpy(url, "/jobs/?QUERY=", sizeof(url));
 
@@ -1344,7 +1359,7 @@ cgiShowJobs(http_t     *http,		/* I - Co
     else
     {
       if (dest)
-        snprintf(url, sizeof(url), "/%s/%s?", cgiGetVariable("SECTION"), dest);
+        snprintf(url, sizeof(url), "/%s/%s?", section, dest);
       else
         strlcpy(url, "/jobs/?", sizeof(url));
 
diff -up cups-1.3.11/cgi-bin/jobs.c.CVE-2009-2820 cups-1.3.11/cgi-bin/jobs.c
--- cups-1.3.11/cgi-bin/jobs.c.CVE-2009-2820	2008-07-11 23:48:49.000000000 +0100
+++ cups-1.3.11/cgi-bin/jobs.c	2009-11-10 14:16:25.076666349 +0000
@@ -57,6 +57,7 @@ main(int  argc,				/* I - Number of comm
   */
 
   cgiSetVariable("SECTION", "jobs");
+  cgiSetVariable("REFRESH_PAGE", "");
 
  /*
   * Connect to the HTTP server...
diff -up cups-1.3.11/cgi-bin/printers.c.CVE-2009-2820 cups-1.3.11/cgi-bin/printers.c
--- cups-1.3.11/cgi-bin/printers.c.CVE-2009-2820	2008-07-11 23:48:49.000000000 +0100
+++ cups-1.3.11/cgi-bin/printers.c	2009-11-10 14:16:25.071790197 +0000
@@ -72,6 +72,7 @@ main(int  argc,				/* I - Number of comm
   */
 
   cgiSetVariable("SECTION", "printers");
+  cgiSetVariable("REFRESH_PAGE", "");
 
  /*
   * See if we are displaying a printer or all printers...
diff -up cups-1.3.11/cgi-bin/template.c.CVE-2009-2820 cups-1.3.11/cgi-bin/template.c
--- cups-1.3.11/cgi-bin/template.c.CVE-2009-2820	2008-07-11 23:48:49.000000000 +0100
+++ cups-1.3.11/cgi-bin/template.c	2009-11-10 14:16:25.072666590 +0000
@@ -639,6 +639,8 @@ cgi_puts(const char *s,			/* I - String 
       fputs("&gt;", out);
     else if (*s == '\"')
       fputs("&quot;", out);
+    else if (*s == '\'')
+      fputs("&#39;", out);
     else if (*s == '&')
       fputs("&amp;", out);
     else
@@ -659,7 +661,7 @@ cgi_puturi(const char *s,		/* I - String
 {
   while (*s)
   {
-    if (strchr("%&+ <>#=", *s) || *s & 128)
+    if (strchr("%@&+ <>#=", *s) || *s < ' ' || *s & 128)
       fprintf(out, "%%%02X", *s & 255);
     else
       putc(*s, out);
diff -up cups-1.3.11/cgi-bin/var.c.CVE-2009-2820 cups-1.3.11/cgi-bin/var.c
--- cups-1.3.11/cgi-bin/var.c.CVE-2009-2820	2009-05-08 05:56:54.000000000 +0100
+++ cups-1.3.11/cgi-bin/var.c	2009-11-10 14:16:25.076666349 +0000
@@ -15,6 +15,7 @@
  * Contents:
  *
  *   cgiCheckVariables()        - Check for the presence of "required" variables.
+ *   cgiClearVariables()        - Clear all form variables.
  *   cgiGetArray()              - Get an element from a form array...
  *   cgiGetFile()               - Get the file (if any) that was submitted in the form.
  *   cgiGetSize()               - Get the size of a form array value.
@@ -135,6 +136,31 @@ cgiCheckVariables(const char *names)	/* 
 
 
 /*
+ * 'cgiClearVariables()' - Clear all form variables.
+ */
+
+void
+cgiClearVariables(void)
+{
+  int		i, j;			/* Looping vars */
+  _cgi_var_t	*v;			/* Current variable */
+
+
+  for (v = form_vars, i = form_count; i > 0; v ++, i --)
+  {
+    _cupsStrFree(v->name);
+    for (j = 0; j < v->nvalues; j ++)
+      if (v->values[j])
+        _cupsStrFree(v->values[j]);
+  }
+
+  form_count = 0;
+
+  cgi_unlink_file();
+}
+
+
+/*
  * 'cgiGetArray()' - Get an element from a form array...
  */
 
@@ -154,7 +180,7 @@ cgiGetArray(const char *name,		/* I - Na
   if (element < 0 || element >= var->nvalues)
     return (NULL);
 
-  return (var->values[element]);
+  return (_cupsStrAlloc(var->values[element]));
 }
 
 
@@ -209,7 +235,7 @@ cgiGetVariable(const char *name)	/* I - 
            var->values[var->nvalues - 1]);
 #endif /* DEBUG */
 
-  return ((var == NULL) ? NULL : var->values[var->nvalues - 1]);
+  return ((var == NULL) ? NULL : _cupsStrAlloc(var->values[var->nvalues - 1]));
 }
 
 
@@ -341,9 +367,9 @@ cgiSetArray(const char *name,		/* I - Na
       var->nvalues = element + 1;
     }
     else if (var->values[element])
-      free((char *)var->values[element]);
+      _cupsStrFree((char *)var->values[element]);
 
-    var->values[element] = strdup(value);
+    var->values[element] = _cupsStrAlloc(value);
   }
 }
 
@@ -388,7 +414,7 @@ cgiSetSize(const char *name,		/* I - Nam
   {
     for (i = size; i < var->nvalues; i ++)
       if (var->values[i])
-        free((void *)(var->values[i]));
+        _cupsStrFree((void *)(var->values[i]));
   }
 
   var->nvalues = size;
@@ -421,9 +447,9 @@ cgiSetVariable(const char *name,	/* I - 
   {
     for (i = 0; i < var->nvalues; i ++)
       if (var->values[i])
-        free((char *)var->values[i]);
+        _cupsStrFree((char *)var->values[i]);
 
-    var->values[0] = strdup(value);
+    var->values[0] = _cupsStrAlloc(value);
     var->nvalues   = 1;
   }
 }
@@ -470,10 +496,10 @@ cgi_add_variable(const char *name,	/* I 
   if ((var->values = calloc(element + 1, sizeof(char *))) == NULL)
     return;
 
-  var->name            = strdup(name);
+  var->name            = _cupsStrAlloc(name);
   var->nvalues         = element + 1;
   var->avalues         = element + 1;
-  var->values[element] = strdup(value);
+  var->values[element] = _cupsStrAlloc(value);
 
   form_count ++;
 }


Index: cups.spec
===================================================================
RCS file: /cvs/pkgs/rpms/cups/F-10/cups.spec,v
retrieving revision 1.466
retrieving revision 1.467
diff -u -p -r1.466 -r1.467
--- cups.spec	3 Nov 2009 17:23:17 -0000	1.466
+++ cups.spec	10 Nov 2009 14:28:02 -0000	1.467
@@ -7,7 +7,7 @@
 Summary: Common Unix Printing System
 Name: cups
 Version: 1.3.11
-Release: 1%{?svn:.svn%{svn}}%{?dist}
+Release: 2%{?svn:.svn%{svn}}%{?dist}
 License: GPLv2
 Group: System Environment/Daemons
 Source: ftp://ftp.easysw.com/pub/cups/test//cups-%{version}%{?svn:svn-r%{svn}}-source.tar.gz
@@ -52,6 +52,10 @@ Patch25: cups-localhost-ipv6.patch
 Patch26: cups-str3023.patch
 Patch30: cups-str3382.patch
 Patch100: cups-lspp.patch
+
+# SECURITY PATCHES:
+Patch200: cups-CVE-2009-2820.patch
+
 Epoch: 1
 Url: http://www.cups.org/
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -193,6 +197,8 @@ module. 
 %patch100 -p1 -b .lspp
 %endif
 
+%patch200 -p1 -b .CVE-2009-2820
+
 sed -i -e '1iMaxLogSize 0' conf/cupsd.conf.in
 
 cp %{SOURCE5} cups-lpd.real
@@ -508,6 +514,9 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/php/modules/*.so
 
 %changelog
+* Tue Nov 10 2009 Tim Waugh <twaugh at redhat.com> 1:1.3.11-2
+- Added fix for CVE-2009-2820 (bug #529833).
+
 * Tue Nov  3 2009 Tim Waugh <twaugh at redhat.com> 1:1.3.11-1
 - 1.3.11.
 




More information about the scm-commits mailing list