diff options
author | 2004-04-04 20:37:21 +0000 | |
---|---|---|
committer | 2004-04-04 20:37:21 +0000 | |
commit | 66a4e2a7556e95829620b942cae6eaacd62bd59e (patch) | |
tree | b2bbe0858a2a19a161c0f313747cfccf2cb63cdc /src | |
parent | add no{doc,man,info} #46661 (diff) | |
download | portage-cvs-66a4e2a7556e95829620b942cae6eaacd62bd59e.tar.gz portage-cvs-66a4e2a7556e95829620b942cae6eaacd62bd59e.tar.bz2 portage-cvs-66a4e2a7556e95829620b942cae6eaacd62bd59e.zip |
Cleanup of the security issues from bug 21923.
file_security_check() is now referenced from file_open
to ensure that the file being operated on is sane.
Diffstat (limited to 'src')
-rw-r--r-- | src/sandbox-1.1/ChangeLog | 10 | ||||
-rw-r--r-- | src/sandbox-1.1/sandbox.c | 7 | ||||
-rw-r--r-- | src/sandbox-1.1/sandbox_futils.c | 112 |
3 files changed, 123 insertions, 6 deletions
diff --git a/src/sandbox-1.1/ChangeLog b/src/sandbox-1.1/ChangeLog index 6996e6b..f889a95 100644 --- a/src/sandbox-1.1/ChangeLog +++ b/src/sandbox-1.1/ChangeLog @@ -1,9 +1,15 @@ # ChangeLog for Path Sandbox # Copyright 2002 Gentoo Technologies, Inc.; Distributed under the GPL v2 -# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/ChangeLog,v 1.32 2004/03/22 01:40:58 carpaski Exp $ +# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/ChangeLog,v 1.33 2004/04/04 20:37:21 carpaski Exp $ + + 04 Apr 2004; Nicholas Jones <carpaski@gentoo.org> libsandbox.c: Added a + file_security_check() function to check random potential exploits on files + that sandbox is to load and read -- Normally sandboxpids.tmp. This fixes + the 'system-crippling' exploits (bug 21923) and catches a few other + potential problems. 20 Mar 2004; Nicholas Jones <carpaski@gentoo.org> Makefile: Updates for - 32/64 bit sandbox. Made CC and LD '?=' values to allow passed in CC to work. + 32/64 bit sandbox. Made CC and LD '?=' values to allow passed in CC to work. 20 Mar 2004; Nicholas Jones <carpaski@gentoo.org> libsandbox.c: bug 42048 -- Fixed the lstat/errno conditions for mkdir <caleb@g.o>. diff --git a/src/sandbox-1.1/sandbox.c b/src/sandbox-1.1/sandbox.c index 7adcf0a..8664b72 100644 --- a/src/sandbox-1.1/sandbox.c +++ b/src/sandbox-1.1/sandbox.c @@ -11,7 +11,7 @@ ** Copyright (C) 2001 Geert Bevin, Uwyn, http://www.uwyn.com ** Distributed under the terms of the GNU General Public License, v2 or later ** Author : Geert Bevin <gbevin@uwyn.com> -** $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/sandbox.c,v 1.15 2004/03/22 01:40:58 carpaski Exp $ +** $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/sandbox.c,v 1.16 2004/04/04 20:37:21 carpaski Exp $ */ /* #define _GNU_SOURCE */ @@ -186,7 +186,7 @@ cleanup() /* Stat the PIDs file, make sure it exists and is a regular file */ if (file_exist(sandbox_pids_file, 1) <= 0) { - perror(">>> pids file is not a regular file"); + fprintf(stderr, ">>> pids file is not a regular file"); success = 0; /* We should really not fail if the pidsfile is missing here, but * rather just exit cleanly, as there is still some cleanup to do */ @@ -798,9 +798,10 @@ main(int argc, char **argv) /* Load our PID into PIDs file */ success = 1; + errno = 0; if (file_exist(sandbox_pids_file, 1) < 0) { success = 0; - fprintf(stderr, ">>> %s is not a regular file", sandbox_pids_file); + fprintf(stderr, ">>> %s is not a regular file\n", sandbox_pids_file); } else { pids_file = file_open(sandbox_pids_file, "r+", 1, 0664, "portage"); if (-1 == pids_file) diff --git a/src/sandbox-1.1/sandbox_futils.c b/src/sandbox-1.1/sandbox_futils.c index 3bed33a..f3bf2b5 100644 --- a/src/sandbox-1.1/sandbox_futils.c +++ b/src/sandbox-1.1/sandbox_futils.c @@ -3,7 +3,7 @@ * Distributed under the terms of the GNU General Public License, v2 or later * Author: Brad House <brad@mainstreetsoftworks.com> * - * $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/sandbox_futils.c,v 1.8 2004/03/22 01:40:58 carpaski Exp $ + * $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/sandbox_futils.c,v 1.9 2004/04/04 20:37:21 carpaski Exp $ * */ @@ -23,10 +23,17 @@ #include <sys/wait.h> #include <unistd.h> #include <fcntl.h> + #include <grp.h> +#include <pwd.h> #include "sandbox.h" +/* BEGIN Prototypes */ +int file_security_check(char *filename); +/* END Prototypes */ + + /* glibc modified getcwd() functions */ char *egetcwd(char *, size_t); @@ -294,6 +301,8 @@ file_open(char *filename, char *mode, int perm_specified, ...) int perm; char *group = NULL; struct group *group_struct; + + file_security_check(filename); if (perm_specified) { va_start(ap, perm_specified); @@ -302,6 +311,7 @@ file_open(char *filename, char *mode, int perm_specified, ...) va_end(ap); } fd = open(filename, file_getmode(mode)); + file_security_check(filename); if (-1 == fd) { snprintf(error, 249, ">>> %s file mode: %s open", filename, mode); perror(error); @@ -327,6 +337,15 @@ file_open(char *filename, char *mode, int perm_specified, ...) } /* Only lock the file if opening succeeded */ if (-1 != fd) { + if(file_security_check(filename) != 0) { + /* Security violation occured between the last check and the */ + /* creation of the file. As SpanKY pointed out there is a race */ + /* condition here, so if there is a problem here we'll mesg and */ + /* bail out to avoid it until we can work and test a better fix. */ + fprintf(stderr, "\n\nSECURITY RACE CONDITION: Problem recurred after creation!\nBAILING OUT\n\n"); + exit(127); + } + if (0 == file_lock(fd, file_locktype(mode), filename)) { close(fd); return -1; @@ -407,4 +426,95 @@ file_exist(char *filename, int checkmode) return 1; } +int file_security_check(char *filename) { /* 0 == fine, >0 == problem */ + struct stat stat_buf; + struct group *group_buf; + struct passwd *passwd_buf; + + passwd_buf = getpwnam("portage"); + group_buf = getgrnam("portage"); + + if((lstat(filename, &stat_buf) == -1) && (errno == ENOENT)) { + /* Doesn't exist. */ + return 0; + } + else { + if((stat_buf.st_nlink) > 1) { /* Security: We are handlinked... */ + if(unlink(filename)) { + fprintf(stderr, + "Unable to delete file in security violation (hardlinked): %s\n", + filename); + exit(127); + } + fprintf(stderr, + "File in security violation (hardlinked): %s\n", + filename); + return 1; + } + else if(S_ISLNK(stat_buf.st_mode)) { /* Security: We are a symlink? */ + fprintf(stderr, + "File in security violation (symlink): %s\n", + filename); + exit(127); + } + else if(0 == S_ISREG(stat_buf.st_mode)) { /* Security: special file */ + fprintf(stderr, + "File in security violation (not regular): %s\n", + filename); + exit(127); + } + else if(stat_buf.st_mode & S_IWOTH) { /* Security: We are o+w? */ + if(unlink(filename)) { + fprintf(stderr, + "Unable to delete file in security violation (world write): %s\n", + filename); + exit(127); + } + fprintf(stderr, + "File in security violation (world write): %s\n", + filename); + return 1; + } + else if( + !((stat_buf.st_uid == 0) || (stat_buf.st_uid == getuid()) || ((passwd_buf!=NULL) && (stat_buf.st_uid == passwd_buf->pw_uid))) || + !((stat_buf.st_gid == 0) || (stat_buf.st_gid == getgid()) || ((group_buf !=NULL) && (stat_buf.st_gid == group_buf->gr_gid))) + ) { /* Security: Owner/Group isn't right. */ + + /* uid = 0 or myuid or portage */ + /* gid = 0 or mygid or portage */ + + if(0) { + fprintf(stderr, "--1: %d,%d,%d,%d\n--2: %d,%d,%d,%d\n", + + (stat_buf.st_uid == 0), + (stat_buf.st_uid == getuid()), + (passwd_buf!=NULL), + (passwd_buf!=NULL)? (stat_buf.st_uid == passwd_buf->pw_uid) : -1, + + (stat_buf.st_gid == 0), + (stat_buf.st_gid == getgid()), + (group_buf !=NULL), + (group_buf !=NULL)? (stat_buf.st_gid == group_buf->gr_gid) : -1); + } + + /* manpage: "The return value may point to static area" */ + /* DO NOT ACTUALLY FREE THIS... It'll segfault. */ + /* if(passwd_buf != NULL) { free(passwd_buf); } */ + /* if(group_buf != NULL) { free(group_buf); } */ + + if(unlink(filename)) { + fprintf(stderr, + "Unable to delete file in security violation (bad owner/group): %s\n", + filename); + exit(127); + } + fprintf(stderr, + "File in security violation (bad owner/group): %s\n", + filename); + return 1; + } + } /* Stat */ + return 0; +} + // vim:expandtab noai:cindent ai |