From d40220801eec992804cb728d51228d19496fffd9 Mon Sep 17 00:00:00 2001 From: msweet Date: Tue, 22 Jul 2014 14:03:19 +0000 Subject: [PATCH] Mirror changes from trunk. git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/branches/branch-1.7@12057 a1ca3aef-8c08-0410-bb20-df032aa958be --- CHANGES.txt | 4 +++- scheduler/client.c | 35 ++++++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index fc659438f2..b6e9f3ee0e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,8 +1,10 @@ -CHANGES.txt - 1.7.4 - 2014-07-18 +CHANGES.txt - 1.7.4 - 2014-07-22 -------------------------------- CHANGES IN CUPS V1.7.5 + - Security: Addressed some more situations where symlinked files would + be served by the web interface (STR #4455) - The LPD backend did not work with some versions of glibc (STR #4452) - CGI scripts did not work (STR #4454) diff --git a/scheduler/client.c b/scheduler/client.c index e5959faf78..366b3515c6 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -3310,7 +3310,7 @@ get_file(cupsd_client_t *con, /* I - Client connection */ * then fallback to the default one... */ - if ((status = stat(filename, filestats)) != 0 && language[0] && + if ((status = lstat(filename, filestats)) != 0 && language[0] && strncmp(con->uri, "/icons/", 7) && strncmp(con->uri, "/ppd/", 5) && strncmp(con->uri, "/rss/", 5) && @@ -3408,13 +3408,13 @@ get_file(cupsd_client_t *con, /* I - Client connection */ plen = len - (ptr - filename); strlcpy(ptr, "index.html", plen); - status = stat(filename, filestats); + status = lstat(filename, filestats); #ifdef HAVE_JAVA if (status) { strlcpy(ptr, "index.class", plen); - status = stat(filename, filestats); + status = lstat(filename, filestats); } #endif /* HAVE_JAVA */ @@ -3422,7 +3422,7 @@ get_file(cupsd_client_t *con, /* I - Client connection */ if (status) { strlcpy(ptr, "index.pl", plen); - status = stat(filename, filestats); + status = lstat(filename, filestats); } #endif /* HAVE_PERL */ @@ -3430,7 +3430,7 @@ get_file(cupsd_client_t *con, /* I - Client connection */ if (status) { strlcpy(ptr, "index.php", plen); - status = stat(filename, filestats); + status = lstat(filename, filestats); } #endif /* HAVE_PHP */ @@ -3438,18 +3438,39 @@ get_file(cupsd_client_t *con, /* I - Client connection */ if (status) { strlcpy(ptr, "index.pyc", plen); - status = stat(filename, filestats); + status = lstat(filename, filestats); } if (status) { strlcpy(ptr, "index.py", plen); - status = stat(filename, filestats); + status = lstat(filename, filestats); } #endif /* HAVE_PYTHON */ } while (status && language[0]); + + /* + * If we've found a symlink, 404 the sucker to avoid disclosing information. + */ + + if (!status && S_ISLNK(filestats->st_mode)) + { + cupsdLogMessage(CUPSD_LOG_INFO, "[Client %d] Symlinks such as \"%s\" are not allowed.", con->http.fd, filename); + return (NULL); + } + + /* + * Similarly, if the file/directory does not have world read permissions, do + * not allow access... + */ + + if (!status && !(filestats->st_mode & S_IROTH)) + { + cupsdLogMessage(CUPSD_LOG_INFO, "[Client %d] Files/directories such as \"%s\" must be world-readable.", con->http.fd, filename); + return (NULL); + } } cupsdLogMessage(CUPSD_LOG_DEBUG2, -- 2.47.2