Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.5:Update
cups.18911
cups-branch-2.2-commit-97cb566568a8c3a9c07c7cce...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File cups-branch-2.2-commit-97cb566568a8c3a9c07c7ccec09f28f5c5015954.diff of Package cups.18911
commit 97cb566568a8c3a9c07c7ccec09f28f5c5015954 Author: Michael R Sweet <michael.r.sweet@gmail.com> Date: Tue May 8 14:59:50 2018 -0700 Fix local privilege escalation to root and sandbox bypasses in scheduler (rdar://37836779, rdar://37836995, rdar://37837252, rdar://37837581) diff --git a/doc/help/man-cups-files.conf.html b/doc/help/man-cups-files.conf.html index 6dd442ef4..e298d8824 100644 --- a/doc/help/man-cups-files.conf.html +++ b/doc/help/man-cups-files.conf.html @@ -115,6 +115,9 @@ The server name may be included in filenames using the string "%s", for example: </pre> The default is "/var/log/cups/page_log". +<dt><a name="PassEnv"></a><b>PassEnv </b><i>variable </i>[ ... <i>variable </i>] +<dd style="margin-left: 5.0em">Passes the specified environment variable(s) to child processes. +Note: the standard CUPS filter and backend environment variables cannot be overridden using this directive. <dt><a name="RemoteRoot"></a><b>RemoteRoot </b><i>username</i> <dd style="margin-left: 5.0em">Specifies the username that is associated with unauthenticated accesses by clients claiming to be the root user. The default is "remroot". @@ -136,6 +139,9 @@ macOS uses its keychain database to store certificates and keys while other plat <dt><a name="ServerRoot"></a><b>ServerRoot </b><i>directory</i> <dd style="margin-left: 5.0em">Specifies the directory containing the server configuration files. The default is "/etc/cups". +<dt><a name="SetEnv"></a><b>SetEnv </b><i>variable value</i> +<dd style="margin-left: 5.0em">Set the specified environment variable to be passed to child processes. +Note: the standard CUPS filter and backend environment variables cannot be overridden using this directive. <dt><a name="StateDir"></a><b>StateDir </b><i>directory</i> <dd style="margin-left: 5.0em">Specifies the directory to use for PID and local certificate files. The default is "/var/run/cups" or "/etc/cups" depending on the platform. diff --git a/doc/help/man-cupsd.conf.html b/doc/help/man-cupsd.conf.html index 943895387..4ba6ecf8f 100644 --- a/doc/help/man-cupsd.conf.html +++ b/doc/help/man-cupsd.conf.html @@ -220,8 +220,6 @@ The default is "1048576" (1MB). <dt><a name="MultipleOperationTimeout"></a><b>MultipleOperationTimeout </b><i>seconds</i> <dd style="margin-left: 5.0em">Specifies the maximum amount of time to allow between files in a multiple file print job. The default is "300" (5 minutes). -<dt><a name="PassEnv"></a><b>PassEnv </b><i>variable </i>[ ... <i>variable </i>] -<dd style="margin-left: 5.0em">Passes the specified environment variable(s) to child processes. <dt><a name="Policy"></a><b><Policy </b><i>name</i><b>> </b>... <b></Policy></b> <dd style="margin-left: 5.0em">Specifies access control for the named policy. <dt><a name="Port"></a><b>Port </b><i>number</i> @@ -273,8 +271,6 @@ command. command. "Full" reports "CUPS 2.0.0 (UNAME) IPP/2.0". The default is "Minimal". -<dt><a name="SetEnv"></a><b>SetEnv </b><i>variable value</i> -<dd style="margin-left: 5.0em">Set the specified environment variable to be passed to child processes. <dt><a name="SSLListen"></a><b>SSLListen </b><i>ipv4-address</i><b>:</b><i>port</i> <dd style="margin-left: 5.0em"><dt><b>SSLListen [</b><i>ipv6-address</i><b>]:</b><i>port</i> <dd style="margin-left: 5.0em"><dt><b>SSLListen *:</b><i>port</i> diff --git a/man/cups-files.conf.man.in b/man/cups-files.conf.man.in index 2ed468661..6ac4e72d3 100644 --- a/man/cups-files.conf.man.in +++ b/man/cups-files.conf.man.in @@ -157,6 +157,11 @@ The server name may be included in filenames using the string "%s", for example: .fi The default is "/var/log/cups/page_log". +.\"#PassEnv +.TP 5 +\fBPassEnv \fIvariable \fR[ ... \fIvariable \fR] +Passes the specified environment variable(s) to child processes. +Note: the standard CUPS filter and backend environment variables cannot be overridden using this directive. .\"#RemoteRoot .TP 5 \fBRemoteRoot \fIusername\fR @@ -191,6 +196,11 @@ macOS uses its keychain database to store certificates and keys while other plat \fBServerRoot \fIdirectory\fR Specifies the directory containing the server configuration files. The default is "/etc/cups". +.\"#SetEnv +.TP 5 +\fBSetEnv \fIvariable value\fR +Set the specified environment variable to be passed to child processes. +Note: the standard CUPS filter and backend environment variables cannot be overridden using this directive. .\"#StateDir .TP 5 \fBStateDir \fIdirectory\fR diff --git a/man/cupsd.conf.man.in b/man/cupsd.conf.man.in index aa59a27e0..15a5fa9e6 100644 --- a/man/cupsd.conf.man.in +++ b/man/cupsd.conf.man.in @@ -342,10 +342,6 @@ The default is "1048576" (1MB). \fBMultipleOperationTimeout \fIseconds\fR Specifies the maximum amount of time to allow between files in a multiple file print job. The default is "300" (5 minutes). -.\"#PassEnv -.TP 5 -\fBPassEnv \fIvariable \fR[ ... \fIvariable \fR] -Passes the specified environment variable(s) to child processes. .\"#Policy .TP 5 \fB<Policy \fIname\fB> \fR... \fB</Policy>\fR @@ -426,10 +422,6 @@ Specifies what information is included in the Server header of HTTP responses. command. "Full" reports "CUPS 2.0.0 (UNAME) IPP/2.0". The default is "Minimal". -.\"#SetEnv -.TP 5 -\fBSetEnv \fIvariable value\fR -Set the specified environment variable to be passed to child processes. .\"#SSLListen .TP 5 \fBSSLListen \fIipv4-address\fB:\fIport\fR diff --git a/scheduler/conf.c b/scheduler/conf.c index 11ad2c024..9c1be7089 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -2928,13 +2928,10 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ /* Line from file */ temp[HTTP_MAX_BUFFER], /* Temporary buffer for value */ - *value, /* Pointer to value */ - *valueptr; /* Pointer into value */ + *value; /* Pointer to value */ int valuelen; /* Length of value */ http_addrlist_t *addrlist, /* Address list */ *addr; /* Current address */ - cups_file_t *incfile; /* Include file */ - char incname[1024]; /* Include filename */ /* @@ -2949,28 +2946,7 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ * Decode the directive... */ - if (!_cups_strcasecmp(line, "Include") && value) - { - /* - * Include filename - */ - - if (value[0] == '/') - strlcpy(incname, value, sizeof(incname)); - else - snprintf(incname, sizeof(incname), "%s/%s", ServerRoot, value); - - if ((incfile = cupsFileOpen(incname, "rb")) == NULL) - cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to include config file \"%s\" - %s", - incname, strerror(errno)); - else - { - read_cupsd_conf(incfile); - cupsFileClose(incfile); - } - } - else if (!_cups_strcasecmp(line, "<Location") && value) + if (!_cups_strcasecmp(line, "<Location") && value) { /* * <Location path> @@ -3366,31 +3342,6 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ cupsdLogMessage(CUPSD_LOG_WARN, "Unknown ServerTokens %s on line %d of %s.", value, linenum, ConfigurationFile); } - else if (!_cups_strcasecmp(line, "PassEnv") && value) - { - /* - * PassEnv variable [... variable] - */ - - for (; *value;) - { - for (valuelen = 0; value[valuelen]; valuelen ++) - if (_cups_isspace(value[valuelen]) || value[valuelen] == ',') - break; - - if (value[valuelen]) - { - value[valuelen] = '\0'; - valuelen ++; - } - - cupsdSetEnv(value, NULL); - - for (value += valuelen; *value; value ++) - if (!_cups_isspace(*value) || *value != ',') - break; - } - } else if (!_cups_strcasecmp(line, "ServerAlias") && value) { /* @@ -3419,30 +3370,6 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ break; } } - else if (!_cups_strcasecmp(line, "SetEnv") && value) - { - /* - * SetEnv variable value - */ - - for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); - - if (*valueptr) - { - /* - * Found a value... - */ - - while (isspace(*valueptr & 255)) - *valueptr++ = '\0'; - - cupsdSetEnv(value, valueptr); - } - else - cupsdLogMessage(CUPSD_LOG_ERROR, - "Missing value for SetEnv directive on line %d of %s.", - linenum, ConfigurationFile); - } else if (!_cups_strcasecmp(line, "AccessLog") || !_cups_strcasecmp(line, "CacheDir") || !_cups_strcasecmp(line, "ConfigFilePerm") || @@ -3456,6 +3383,7 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ !_cups_strcasecmp(line, "LogFilePerm") || !_cups_strcasecmp(line, "LPDConfigFile") || !_cups_strcasecmp(line, "PageLog") || + !_cups_strcasecmp(line, "PassEnv") || !_cups_strcasecmp(line, "Printcap") || !_cups_strcasecmp(line, "PrintcapFormat") || !_cups_strcasecmp(line, "RemoteRoot") || @@ -3465,6 +3393,7 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ !_cups_strcasecmp(line, "ServerKey") || !_cups_strcasecmp(line, "ServerKeychain") || !_cups_strcasecmp(line, "ServerRoot") || + !_cups_strcasecmp(line, "SetEnv") || !_cups_strcasecmp(line, "SMBConfigFile") || !_cups_strcasecmp(line, "StateDir") || !_cups_strcasecmp(line, "SystemGroup") || @@ -3494,10 +3423,49 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ static int /* O - 1 on success, 0 on failure */ read_cups_files_conf(cups_file_t *fp) /* I - File to read from */ { - int linenum; /* Current line number */ + int i, /* Looping var */ + linenum; /* Current line number */ char line[HTTP_MAX_BUFFER], /* Line from file */ *value; /* Value from line */ struct group *group; /* Group */ + static const char * const prohibited_env[] = + { /* Prohibited environment variables */ + "APPLE_LANGUAGE", + "AUTH_DOMAIN", + "AUTH_INFO_REQUIRED", + "AUTH_NEGOTIATE", + "AUTH_PASSWORD", + "AUTH_UID", + "AUTH_USERNAME", + "CHARSET", + "CLASS", + "CLASSIFICATION", + "CONTENT_TYPE", + "CUPS_CACHEDIR", + "CUPS_DATADIR", + "CUPS_DOCROOT", + "CUPS_FILETYPE", + "CUPS_FONTPATH", + "CUPS_MAX_MESSAGE", + "CUPS_REQUESTROOT", + "CUPS_SERVERBIN", + "CUPS_SERVERROOT", + "CUPS_STATEDIR", + "DEVICE_URI", + "FINAL_CONTENT_TYPE", + "HOME", + "LANG", + "PPD", + "PRINTER", + "PRINTER_INFO", + "PRINTER_LOCATION", + "PRINTER_STATE_REASONS", + "RIP_CACHE", + "SERVER_ADMIN", + "SOFTWARE", + "TMPDIR", + "USER" + }; /* @@ -3535,6 +3503,47 @@ read_cups_files_conf(cups_file_t *fp) /* I - File to read from */ } } } + else if (!_cups_strcasecmp(line, "PassEnv") && value) + { + /* + * PassEnv variable [... variable] + */ + + int valuelen; /* Length of variable name */ + + for (; *value;) + { + for (valuelen = 0; value[valuelen]; valuelen ++) + if (_cups_isspace(value[valuelen]) || value[valuelen] == ',') + break; + + if (value[valuelen]) + { + value[valuelen] = '\0'; + valuelen ++; + } + + for (i = 0; i < (int)(sizeof(prohibited_env) / sizeof(prohibited_env[0])); i ++) + { + if (!strcmp(value, prohibited_env[i])) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Environment variable \"%s\" cannot be passed through on line %d of %s.", value, linenum, CupsFilesFile); + + if (FatalErrors & CUPSD_FATAL_CONFIG) + return (0); + else + break; + } + } + + if (i >= (int)(sizeof(prohibited_env) / sizeof(prohibited_env[0]))) + cupsdSetEnv(value, NULL); + + for (value += valuelen; *value; value ++) + if (!_cups_isspace(*value) || *value != ',') + break; + } + } else if (!_cups_strcasecmp(line, "PrintcapFormat") && value) { /* @@ -3580,6 +3589,46 @@ read_cups_files_conf(cups_file_t *fp) /* I - File to read from */ return (0); } } + else if (!_cups_strcasecmp(line, "SetEnv") && value) + { + /* + * SetEnv variable value + */ + + char *valueptr; /* Pointer to environment variable value */ + + for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); + + if (*valueptr) + { + /* + * Found a value... + */ + + while (isspace(*valueptr & 255)) + *valueptr++ = '\0'; + + for (i = 0; i < (int)(sizeof(prohibited_env) / sizeof(prohibited_env[0])); i ++) + { + if (!strcmp(value, prohibited_env[i])) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Environment variable \"%s\" cannot be set on line %d of %s.", value, linenum, CupsFilesFile); + + if (FatalErrors & CUPSD_FATAL_CONFIG) + return (0); + else + break; + } + } + + if (i >= (int)(sizeof(prohibited_env) / sizeof(prohibited_env[0]))) + cupsdSetEnv(value, valueptr); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Missing value for SetEnv directive on line %d of %s.", + linenum, ConfigurationFile); + } else if (!_cups_strcasecmp(line, "SystemGroup") && value) { /* diff --git a/scheduler/job.c b/scheduler/job.c index 86e75e65c..ed8267d5d 100644 --- a/scheduler/job.c +++ b/scheduler/job.c @@ -1,7 +1,7 @@ /* * Job management routines for the CUPS scheduler. * - * Copyright 2007-2017 by Apple Inc. + * Copyright 2007-2018 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -4774,6 +4774,18 @@ start_job(cupsd_job_t *job, /* I - Job ID */ job->profile = cupsdCreateProfile(job->id, 0); job->bprofile = cupsdCreateProfile(job->id, 1); +#ifdef HAVE_SANDBOX_H + if ((!job->profile || !job->bprofile) && UseSandboxing && Sandboxing != CUPSD_SANDBOXING_OFF) + { + /* + * Failure to create the sandbox profile means something really bad has + * happened and we need to shutdown immediately. + */ + + return; + } +#endif /* HAVE_SANDBOX_H */ + /* * Create the status pipes and buffer... */ diff --git a/scheduler/process.c b/scheduler/process.c index 5c01b4b11..a09d49884 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -1,7 +1,7 @@ /* * Process management routines for the CUPS scheduler. * - * Copyright 2007-2017 by Apple Inc. + * Copyright 2007-2018 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -102,9 +102,13 @@ cupsdCreateProfile(int job_id, /* I - Job ID or 0 for none */ if ((fp = cupsTempFile2(profile, sizeof(profile))) == NULL) { + /* + * This should never happen, and is fatal when sandboxing is enabled. + */ + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d, allow_networking=%d) = NULL", job_id, allow_networking); - cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create security profile: %s", - strerror(errno)); + cupsdLogMessage(CUPSD_LOG_EMERG, "Unable to create security profile: %s", strerror(errno)); + kill(getpid(), SIGTERM); return (NULL); } @@ -201,10 +205,8 @@ cupsdCreateProfile(int job_id, /* I - Job ID or 0 for none */ " #\"^%s/\"" /* TempDir/... */ " #\"^%s$\"" /* CacheDir */ " #\"^%s/\"" /* CacheDir/... */ - " #\"^%s$\"" /* StateDir */ - " #\"^%s/\"" /* StateDir/... */ "))\n", - temp, temp, cache, cache, state, state); + temp, temp, cache, cache); /* Read common folders */ cupsFilePrintf(fp, "(allow file-read-data file-read-metadata\n" @@ -246,8 +248,10 @@ cupsdCreateProfile(int job_id, /* I - Job ID or 0 for none */ " #\"^%s/\"" /* ServerBin/... */ " #\"^%s$\"" /* ServerRoot */ " #\"^%s/\"" /* ServerRoot/... */ + " #\"^%s$\"" /* StateDir */ + " #\"^%s/\"" /* StateDir/... */ "))\n", - request, request, bin, bin, root, root); + request, request, bin, bin, root, root, state, state); if (Sandboxing == CUPSD_SANDBOXING_RELAXED) { /* Limited write access to /Library/Printers/... */ diff --git a/scheduler/server.c b/scheduler/server.c index d28cd4a0b..63fcf90bf 100644 --- a/scheduler/server.c +++ b/scheduler/server.c @@ -1,7 +1,7 @@ /* * Server start/stop routines for the CUPS scheduler. * - * Copyright 2007-2017 by Apple Inc. + * Copyright 2007-2018 by Apple Inc. * Copyright 1997-2006 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -38,16 +38,28 @@ void cupsdStartServer(void) { /* - * Start color management (as needed)... + * Create the default security profile... */ - cupsdStartColor(); + DefaultProfile = cupsdCreateProfile(0, 1); + +#ifdef HAVE_SANDBOX_H + if (!DefaultProfile && UseSandboxing && Sandboxing != CUPSD_SANDBOXING_OFF) + { + /* + * Failure to create the sandbox profile means something really bad has + * happened and we need to shutdown immediately. + */ + + return; + } +#endif /* HAVE_SANDBOX_H */ /* - * Create the default security profile... + * Start color management (as needed)... */ - DefaultProfile = cupsdCreateProfile(0, 1); + cupsdStartColor(); /* * Startup all the networking stuff... diff --git a/test/run-stp-tests.sh b/test/run-stp-tests.sh index 1063be4d0..056e8e5c8 100755 --- a/test/run-stp-tests.sh +++ b/test/run-stp-tests.sh @@ -492,11 +492,6 @@ StrictConformance Yes Browsing Off Listen localhost:$port Listen $BASE/sock -PassEnv DYLD_LIBRARY_PATH -PassEnv LD_LIBRARY_PATH -PassEnv LD_PRELOAD -PassEnv LOCALEDIR -PassEnv SHLIB_PATH MaxSubscriptions 3 MaxLogSize 0 AccessLogLevel actions @@ -532,6 +527,12 @@ TempDir $BASE/spool/temp AccessLog $BASE/log/access_log ErrorLog $BASE/log/error_log PageLog $BASE/log/page_log + +PassEnv DYLD_LIBRARY_PATH +PassEnv LD_LIBRARY_PATH +PassEnv LD_PRELOAD +PassEnv LOCALEDIR +PassEnv SHLIB_PATH EOF if test $ssltype != 0 -a `uname` = Darwin; then
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor