summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2015-06-08 18:32:35 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2015-06-08 18:32:35 +0000
commit5e6c3df7c0d322aa83a6c7bf94ab63a3f479a938 (patch)
treeb6f610973012651cf7d9c521c879e3d7267ca0ac
parentc59e07c6742e25ef7111714e890f489bdc4a376c (diff)
Security: Fix CERT VU #810572 exploiting the dynamic linker (STR #4609)
git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@12700 a1ca3aef-8c08-0410-bb20-df032aa958be
-rw-r--r--CHANGES-2.0.txt1
-rw-r--r--cgi-bin/ipp-var.c18
-rw-r--r--cgi-bin/template.c36
-rw-r--r--scheduler/client.c9
-rw-r--r--scheduler/env.c34
-rw-r--r--scheduler/ipp.c95
-rw-r--r--scheduler/job.c17
-rw-r--r--scheduler/main.c17
8 files changed, 66 insertions, 161 deletions
diff --git a/CHANGES-2.0.txt b/CHANGES-2.0.txt
index 2f542edf8..85dba8aad 100644
--- a/CHANGES-2.0.txt
+++ b/CHANGES-2.0.txt
@@ -3,6 +3,7 @@ CHANGES-2.0.txt
CHANGES IN CUPS V2.0.3
+ - Security: Fixed CERT VU #810572 exploiting the dynamic linker (STR #4609)
- Restored missing generic printer icon file (STR #4587)
- Fixed logging of configuration errors to show up as errors (STR #4582)
- Fixed potential buffer overflows in raster code and filters
diff --git a/cgi-bin/ipp-var.c b/cgi-bin/ipp-var.c
index 9682d791e..2aabe5322 100644
--- a/cgi-bin/ipp-var.c
+++ b/cgi-bin/ipp-var.c
@@ -3,7 +3,7 @@
*
* CGI <-> IPP variable routines for CUPS.
*
- * Copyright 2007-2014 by Apple Inc.
+ * Copyright 2007-2015 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -1202,21 +1202,7 @@ cgiSetIPPObjectVars(
* Rewrite URIs...
*/
- if (!strcmp(name, "member_uris"))
- {
- char url[1024]; /* URL for class member... */
-
-
- cgiRewriteURL(attr->values[i].string.text, url,
- sizeof(url), NULL);
-
- snprintf(valptr, sizeof(value) - (size_t)(valptr - value),
- "<A HREF=\"%s\">%s</A>", url,
- strrchr(attr->values[i].string.text, '/') + 1);
- }
- else
- cgiRewriteURL(attr->values[i].string.text, valptr,
- (int)(sizeof(value) - (size_t)(valptr - value)), NULL);
+ cgiRewriteURL(attr->values[i].string.text, valptr, (int)(sizeof(value) - (size_t)(valptr - value)), NULL);
break;
}
diff --git a/cgi-bin/template.c b/cgi-bin/template.c
index a606844a6..532544174 100644
--- a/cgi-bin/template.c
+++ b/cgi-bin/template.c
@@ -3,7 +3,7 @@
*
* CGI template function.
*
- * Copyright 2007-2014 by Apple Inc.
+ * Copyright 2007-2015 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -648,39 +648,7 @@ cgi_puts(const char *s, /* I - String to output */
while (*s)
{
if (*s == '<')
- {
- /*
- * Pass <A HREF="url"> and </A>, otherwise quote it...
- */
-
- if (!_cups_strncasecmp(s, "<A HREF=\"", 9))
- {
- fputs("<A HREF=\"", out);
- s += 9;
-
- while (*s && *s != '\"')
- {
- if (*s == '&')
- fputs("&amp;", out);
- else
- putc(*s, out);
-
- s ++;
- }
-
- if (*s)
- s ++;
-
- fputs("\">", out);
- }
- else if (!_cups_strncasecmp(s, "</A>", 4))
- {
- fputs("</A>", out);
- s += 3;
- }
- else
- fputs("&lt;", out);
- }
+ fputs("&lt;", out);
else if (*s == '>')
fputs("&gt;", out);
else if (*s == '\"')
diff --git a/scheduler/client.c b/scheduler/client.c
index 50464a524..672144541 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -3,7 +3,7 @@
*
* Client routines for the CUPS scheduler.
*
- * Copyright 2007-2014 by Apple Inc.
+ * Copyright 2007-2015 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* This file contains Kerberos support code, copyright 2006 by
@@ -484,7 +484,12 @@ cupsdCloseClient(cupsd_client_t *con) /* I - Client to close */
httpClose(con->http);
- cupsdClearString(&con->filename);
+ if (con->filename)
+ {
+ unlink(con->filename);
+ cupsdClearString(&con->filename);
+ }
+
cupsdClearString(&con->command);
cupsdClearString(&con->options);
cupsdClearString(&con->query_string);
diff --git a/scheduler/env.c b/scheduler/env.c
index b41fea118..d5c154fcd 100644
--- a/scheduler/env.c
+++ b/scheduler/env.c
@@ -1,27 +1,16 @@
/*
* "$Id$"
*
- * Environment management routines for the CUPS scheduler.
+ * Environment management routines for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products, all rights reserved.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * cupsdInitEnv() - Initialize the current environment with standard
- * variables.
- * cupsdLoadEnv() - Copy common environment variables into an array.
- * cupsdSetEnv() - Set a common environment variable.
- * cupsdSetEnvf() - Set a formatted common environment variable.
- * cupsdUpdateEnv() - Update the environment for the configured directories.
- * clear_env() - Clear common environment variables.
- * find_env() - Find a common environment variable.
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*/
/*
@@ -131,6 +120,13 @@ cupsdSetEnv(const char *name, /* I - Name of variable */
return;
/*
+ * Do not allow dynamic linker variables when running as root...
+ */
+
+ if (!RunUser && (!strncmp(name, "DYLD_", 5) || !strncmp(name, "LD_", 3)))
+ return;
+
+ /*
* See if this variable has already been defined...
*/
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index bebae49ac..57c882d05 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -3,7 +3,7 @@
*
* IPP routines for the CUPS scheduler.
*
- * Copyright 2007-2014 by Apple Inc.
+ * Copyright 2007-2015 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* This file contains Kerberos support code, copyright 2006 by
@@ -409,8 +409,7 @@ cupsdProcessIPPRequest(
* Remote unauthenticated user masquerading as local root...
*/
- _cupsStrFree(username->values[0].string.text);
- username->values[0].string.text = _cupsStrAlloc(RemoteRoot);
+ ippSetString(con->request, &username, 0, RemoteRoot);
}
}
@@ -1573,7 +1572,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */
cupsdSetString(&job->username, con->username);
if (attr)
- cupsdSetString(&attr->values[0].string.text, con->username);
+ ippSetString(job->attrs, &attr, 0, con->username);
}
else if (attr)
{
@@ -1591,9 +1590,8 @@ add_job(cupsd_client_t *con, /* I - Client connection */
"job-originating-user-name", NULL, job->username);
else
{
- attr->group_tag = IPP_TAG_JOB;
- _cupsStrFree(attr->name);
- attr->name = _cupsStrAlloc("job-originating-user-name");
+ ippSetGroupTag(job->attrs, &attr, IPP_TAG_JOB);
+ ippSetName(job->attrs, &attr, "job-originating-user-name");
}
if (con->username[0] || auth_info)
@@ -1627,48 +1625,11 @@ add_job(cupsd_client_t *con, /* I - Client connection */
* Also, we can only have 1 value and it must be a name value.
*/
- switch (attr->value_tag)
- {
- case IPP_TAG_STRING :
- case IPP_TAG_TEXTLANG :
- case IPP_TAG_NAMELANG :
- case IPP_TAG_TEXT :
- case IPP_TAG_NAME :
- case IPP_TAG_KEYWORD :
- case IPP_TAG_URI :
- case IPP_TAG_URISCHEME :
- case IPP_TAG_CHARSET :
- case IPP_TAG_LANGUAGE :
- case IPP_TAG_MIMETYPE :
- /*
- * Free old strings...
- */
-
- for (i = 0; i < attr->num_values; i ++)
- {
- _cupsStrFree(attr->values[i].string.text);
- attr->values[i].string.text = NULL;
- if (attr->values[i].string.language)
- {
- _cupsStrFree(attr->values[i].string.language);
- attr->values[i].string.language = NULL;
- }
- }
-
- default :
- break;
- }
-
- /*
- * Use the default connection hostname instead...
- */
-
- attr->value_tag = IPP_TAG_NAME;
- attr->num_values = 1;
- attr->values[0].string.text = _cupsStrAlloc(con->http->hostname);
+ ippDeleteAttribute(job->attrs, attr);
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-originating-host-name", NULL, con->http->hostname);
}
-
- attr->group_tag = IPP_TAG_JOB;
+ else
+ ippSetGroupTag(job->attrs, &attr, IPP_TAG_JOB);
}
else
{
@@ -1763,8 +1724,8 @@ add_job(cupsd_client_t *con, /* I - Client connection */
attr = ippAddStrings(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-sheets",
2, NULL, NULL);
- attr->values[0].string.text = _cupsStrRetain(printer->job_sheets[0]);
- attr->values[1].string.text = _cupsStrRetain(printer->job_sheets[1]);
+ ippSetString(job->attrs, &attr, 0, printer->job_sheets[0]);
+ ippSetString(job->attrs, &attr, 1, printer->job_sheets[1]);
}
job->job_sheets = attr;
@@ -1790,7 +1751,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */
* Force the leading banner to have the classification on it...
*/
- cupsdSetString(&attr->values[0].string.text, Classification);
+ ippSetString(job->attrs, &attr, 0, Classification);
cupsdLogJob(job, CUPSD_LOG_NOTICE, "CLASSIFICATION FORCED "
"job-sheets=\"%s,none\", "
@@ -1807,7 +1768,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */
* Can't put two different security markings on the same document!
*/
- cupsdSetString(&attr->values[1].string.text, attr->values[0].string.text);
+ ippSetString(job->attrs, &attr, 1, attr->values[0].string.text);
cupsdLogJob(job, CUPSD_LOG_NOTICE, "CLASSIFICATION FORCED "
"job-sheets=\"%s,%s\", "
@@ -1847,18 +1808,18 @@ add_job(cupsd_client_t *con, /* I - Client connection */
if (attr->num_values > 1 &&
!strcmp(attr->values[0].string.text, attr->values[1].string.text))
{
- cupsdSetString(&(attr->values[0].string.text), Classification);
- cupsdSetString(&(attr->values[1].string.text), Classification);
+ ippSetString(job->attrs, &attr, 0, Classification);
+ ippSetString(job->attrs, &attr, 1, Classification);
}
else
{
if (attr->num_values == 1 ||
strcmp(attr->values[0].string.text, "none"))
- cupsdSetString(&(attr->values[0].string.text), Classification);
+ ippSetString(job->attrs, &attr, 0, Classification);
if (attr->num_values > 1 &&
strcmp(attr->values[1].string.text, "none"))
- cupsdSetString(&(attr->values[1].string.text), Classification);
+ ippSetString(job->attrs, &attr, 1, Classification);
}
if (attr->num_values > 1)
@@ -3097,8 +3058,8 @@ authenticate_job(cupsd_client_t *con, /* I - Client connection */
if (attr)
{
- attr->value_tag = IPP_TAG_KEYWORD;
- cupsdSetString(&(attr->values[0].string.text), "no-hold");
+ ippSetValueTag(job->attrs, &attr, IPP_TAG_KEYWORD);
+ ippSetString(job->attrs, &attr, 0, "no-hold");
}
/*
@@ -8248,11 +8209,7 @@ print_job(cupsd_client_t *con, /* I - Client connection */
filetype->type);
if (format)
- {
- _cupsStrFree(format->values[0].string.text);
-
- format->values[0].string.text = _cupsStrAlloc(mimetype);
- }
+ ippSetString(con->request, &format, 0, mimetype);
else
ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
"document-format", NULL, mimetype);
@@ -8800,10 +8757,8 @@ release_job(cupsd_client_t *con, /* I - Client connection */
if (attr)
{
- _cupsStrFree(attr->values[0].string.text);
-
- attr->value_tag = IPP_TAG_KEYWORD;
- attr->values[0].string.text = _cupsStrAlloc("no-hold");
+ ippSetValueTag(job->attrs, &attr, IPP_TAG_KEYWORD);
+ ippSetString(job->attrs, &attr, 0, "no-hold");
cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, cupsdFindDest(job->dest), job,
"Job job-hold-until value changed by user.");
@@ -9500,11 +9455,7 @@ send_document(cupsd_client_t *con, /* I - Client connection */
if ((jformat = ippFindAttribute(job->attrs, "document-format",
IPP_TAG_MIMETYPE)) != NULL)
- {
- _cupsStrFree(jformat->values[0].string.text);
-
- jformat->values[0].string.text = _cupsStrAlloc(mimetype);
- }
+ ippSetString(job->attrs, &jformat, 0, mimetype);
else
ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
"document-format", NULL, mimetype);
diff --git a/scheduler/job.c b/scheduler/job.c
index 393dceca9..956f9ffa9 100644
--- a/scheduler/job.c
+++ b/scheduler/job.c
@@ -377,7 +377,7 @@ cupsdCheckJobs(void)
if ((attr = ippFindAttribute(job->attrs, "job-actual-printer-uri",
IPP_TAG_URI)) != NULL)
- cupsdSetString(&attr->values[0].string.text, printer->uri);
+ ippSetString(job->attrs, &attr, 0, printer->uri);
else
ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI,
"job-actual-printer-uri", NULL, printer->uri);
@@ -2099,7 +2099,7 @@ cupsdMoveJob(cupsd_job_t *job, /* I - Job */
if ((attr = ippFindAttribute(job->attrs, "job-printer-uri",
IPP_TAG_URI)) != NULL)
- cupsdSetString(&(attr->values[0].string.text), p->uri);
+ ippSetString(job->attrs, &attr, 0, p->uri);
cupsdAddEvent(CUPSD_EVENT_JOB_STOPPED, p, job,
"Job #%d moved from %s to %s.", job->id, olddest,
@@ -2296,7 +2296,7 @@ cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */
attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
if (attr)
- cupsdSetString(&(attr->values[0].string.text), when);
+ ippSetString(job->attrs, &attr, 0, when);
else
attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD,
"job-hold-until", NULL, when);
@@ -2551,8 +2551,8 @@ cupsdSetJobState(
if (attr)
{
- attr->value_tag = IPP_TAG_KEYWORD;
- cupsdSetString(&(attr->values[0].string.text), "no-hold");
+ ippSetValueTag(job->attrs, &attr, IPP_TAG_KEYWORD);
+ ippSetString(job->attrs, &attr, 0, "no-hold");
}
default :
@@ -4607,7 +4607,7 @@ start_job(cupsd_job_t *job, /* I - Job ID */
"job-printer-state-message",
IPP_TAG_TEXT);
if (job->printer_message)
- cupsdSetString(&(job->printer_message->values[0].string.text), "");
+ ippSetString(job->attrs, &job->printer_message, 0, "");
ippSetString(job->attrs, &job->reasons, 0, "job-printing");
cupsdSetJobState(job, IPP_JOB_PROCESSING, CUPSD_JOB_DEFAULT, NULL);
@@ -5268,15 +5268,14 @@ update_job_attrs(cupsd_job_t *job, /* I - Job to update */
if (job->state_value != IPP_JOB_PROCESSING &&
job->status_level == CUPSD_LOG_INFO)
{
- cupsdSetString(&(job->printer_message->values[0].string.text), "");
+ ippSetString(job->attrs, &job->printer_message, 0, "");
job->dirty = 1;
cupsdMarkDirty(CUPSD_DIRTY_JOBS);
}
else if (job->printer->state_message[0] && do_message)
{
- cupsdSetString(&(job->printer_message->values[0].string.text),
- job->printer->state_message);
+ ippSetString(job->attrs, &job->printer_message, 0, job->printer->state_message);
job->dirty = 1;
cupsdMarkDirty(CUPSD_DIRTY_JOBS);
diff --git a/scheduler/main.c b/scheduler/main.c
index d5015aa4d..e03f88d79 100644
--- a/scheduler/main.c
+++ b/scheduler/main.c
@@ -1156,8 +1156,8 @@ cupsdAddString(cups_array_t **a, /* IO - String array */
if (!*a)
*a = cupsArrayNew3((cups_array_func_t)strcmp, NULL,
(cups_ahash_func_t)NULL, 0,
- (cups_acopy_func_t)_cupsStrAlloc,
- (cups_afree_func_t)_cupsStrFree);
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free);
return (cupsArrayAdd(*a, (char *)s));
}
@@ -1187,7 +1187,7 @@ cupsdClearString(char **s) /* O - String value */
{
if (s && *s)
{
- _cupsStrFree(*s);
+ free(*s);
*s = NULL;
}
}
@@ -1268,10 +1268,10 @@ cupsdSetString(char **s, /* O - New string */
return;
if (*s)
- _cupsStrFree(*s);
+ free(*s);
if (v)
- *s = _cupsStrAlloc(v);
+ *s = strdup(v);
else
*s = NULL;
}
@@ -1302,13 +1302,13 @@ cupsdSetStringf(char **s, /* O - New string */
vsnprintf(v, sizeof(v), f, ap);
va_end(ap);
- *s = _cupsStrAlloc(v);
+ *s = strdup(v);
}
else
*s = NULL;
if (olds)
- _cupsStrFree(olds);
+ free(olds);
}
@@ -1468,8 +1468,7 @@ process_children(void)
}
if (job->printer_message)
- cupsdSetString(&(job->printer_message->values[0].string.text),
- message);
+ ippSetString(job->attrs, &job->printer_message, 0, message);
}
}