aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNicholas Jones <carpaski@gentoo.org>2004-04-04 20:37:21 +0000
committerNicholas Jones <carpaski@gentoo.org>2004-04-04 20:37:21 +0000
commit66a4e2a7556e95829620b942cae6eaacd62bd59e (patch)
treeb2bbe0858a2a19a161c0f313747cfccf2cb63cdc /src
parentadd no{doc,man,info} #46661 (diff)
downloadportage-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/ChangeLog10
-rw-r--r--src/sandbox-1.1/sandbox.c7
-rw-r--r--src/sandbox-1.1/sandbox_futils.c112
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