diff options
-rw-r--r-- | src/sandbox-1.1/ChangeLog | 265 | ||||
-rw-r--r-- | src/sandbox-1.1/Makefile | 81 | ||||
-rw-r--r-- | src/sandbox-1.1/canonicalize.c | 173 | ||||
-rwxr-xr-x | src/sandbox-1.1/create-localdecls | 115 | ||||
-rw-r--r-- | src/sandbox-1.1/getcwd.c | 511 | ||||
-rw-r--r-- | src/sandbox-1.1/libctest.c | 7 | ||||
-rw-r--r-- | src/sandbox-1.1/libsandbox.c | 1383 | ||||
-rw-r--r-- | src/sandbox-1.1/sandbox.bashrc | 8 | ||||
-rw-r--r-- | src/sandbox-1.1/sandbox.c | 863 | ||||
-rw-r--r-- | src/sandbox-1.1/sandbox.h | 68 | ||||
-rw-r--r-- | src/sandbox-1.1/sandbox_futils.c | 513 | ||||
-rw-r--r-- | src/sandbox/Makefile | 30 | ||||
-rw-r--r-- | src/sandbox/libsandbox.c | 873 | ||||
-rw-r--r-- | src/sandbox/problems/Makefile | 31 | ||||
-rw-r--r-- | src/sandbox/problems/libsandbox_emacsbug.c | 34 | ||||
-rw-r--r-- | src/sandbox/problems/libsandbox_muttbug.c | 24 | ||||
-rw-r--r-- | src/sandbox/problems/sandbox_dev_fd_foo.c | 42 | ||||
-rw-r--r-- | src/sandbox/problems/sandbox_muttbug.c | 43 | ||||
-rw-r--r-- | src/sandbox/sandbox.bashrc | 8 | ||||
-rw-r--r-- | src/sandbox/sandbox.c | 921 |
20 files changed, 0 insertions, 5993 deletions
diff --git a/src/sandbox-1.1/ChangeLog b/src/sandbox-1.1/ChangeLog deleted file mode 100644 index 334af836f..000000000 --- a/src/sandbox-1.1/ChangeLog +++ /dev/null @@ -1,265 +0,0 @@ -# ChangeLog for Path Sandbox -# Copyright 1999-2004 Gentoo Foundation; Distributed under the GPL v2 -# $Id: /var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/ChangeLog,v 1.37.2.3 2004/12/01 22:14:09 carpaski Exp $ - - 01 Dec 2004; Nicholas Jones <carpaski@gentoo.org> libsandbox.c, sandbox.c: - Added ferringb's code to handle the sandbox pid overflow problem. - - 07 Nov 2004; Brian Harring <ferringb@gentoo.org> libsandbox.c: c99 standard - allowing data and code mixing in code isn't available for gcc 2.95- should fix - bug #70351. - - 03 Nov 2004; Brian Harring <ferringb@gentoo.org> libsandbox.c, sandbox_futils.c: - Fixups, and a hole closed regarding verifying SANDBOX_(|DEBUG_)LOG is sane. - - 02 Aug 2004; Nicholas Jones <carpaski@gentoo.org> libsandbox.c: Code from - Seth Robertson that tracked down all adjuct flags for read operations that - do not invoke a write operation. - - 04 Apr 2004; Nicholas Jones <carpaski@gentoo.org> libsandbox.c, sandbox.c: - Another fix from jstubbs regarding a free() on a stack variable for the - environment -- tracking now prevents extraneous free()'s segfault. - - 04 Apr 2004; Nicholas Jones <carpaski@gentoo.org> libsandbox.c, sandbox.c: - J. Stubbs tracked down a new bug where mkdir was failing to the patch on - the lstat in mkdir... it now only returns 0 or -1 as documented for mkdir. - Also remove the errno = ESUCCESS settings as documentation points out that - a library isn't allowed to do that. - - 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. - - 20 Mar 2004; Nicholas Jones <carpaski@gentoo.org> libsandbox.c: - bug 42048 -- Fixed the lstat/errno conditions for mkdir <caleb@g.o>. - Added the 64/32 bit sandbox patch for AMD64 bug 32963 <brad/azarah>. - - 29 Feb 2004; Martin Schlemmer <azarah@gentoo.org> sandbox.c, sandbox_futils.c : - Fix permissions and group of pids file and logs. Permissions should be 0664 - and group should be 'portage'. Bug #34260. - - 28 Feb 2004; Martin Schlemmer <azarah@gentoo.org> libsandbox.c : - Besides a small cleanup, redo how we replace LD_PRELOAD in the environ passed - to the real execve (in our execve wrapper). Seems that on some arches (sparc - among others) do not allow us to tamper with the readonly copy passed to - execve, so pass our own copy of the environment. Bug #42290. - - 11 Jan 2004; Nicholas Jones <carpaski@gentoo.org> create-decls: - Changed tail to head and added a notice about duration of glibc check. - - 21 Dec 2003; Nicholas Jones <carpaski@gentoo.org> create-decls: - Changed the glibc subversion check to use /usr/bin/* instead of /bin/sh - as there isn't a guarentee that it is dynamic. - - 02 Nov 2003; Martin Schlemmer <azarah@gentoo.org> libsandbox.c : - If 'file' passed to before_syscall(const char *func, const char *file) is - invalid, we should set errno to ENOENT, and not EINVAL. This should - close bug #32238. - - 14 Oct 2003; Martin Schlemmer <azarah@gentoo.org> libsandbox.c : - Fix a bug that occurs mainly on 64bit arch, where the file passed to - the functions we wrap, is invalid, and then cause canonicalize to pass - garbage to before_syscall(), thanks to great detective work from - Andrea Luzzardi <al@sig11.org> (bug #29846). - - 13 Oct 2003; Martin Schlemmer <azarah@gentoo.org> create-localdecls : - Add a uClibc detection patch from Peter S. Mazinger <ps.m@gmx.net>. - - 13 Oct 2003; Martin Schlemmer <azarah@gentoo.org> libsandbox.c : - Fix a bug in libsandbox.c 's checking in the rename wrapper - it basically - only checked the destination patch, and not the source, so we could move - a protected file to a unprotected directory, and then delete/modify it. - Thanks to Andrea Luzzardi (scox) <al@sig11.org>, bug #30992, for this fix. - - 12 Oct 2003; Nicholas Jones <carpaski@gentoo.org> sandbox.c : - Added python2.3 to the predict section/variable. - - 28 Sep 2003; Martin Schlemmer <azarah@gentoo.org> libsandbox.c, sandbox.c, - sandbox.h, sandbox_futils.c : - Add support to set the pids file via SANDBOX_PIDS_FILE at startup. If - it is not set, it will revert to its old value. - - 27 Sep 2003; Martin Schlemmer <azarah@gentoo.org> libsandbox.c : - Fix our mkdir wrapper to check if the dir exist, and return EEXIST if so, - rather than failing with a violation, bug #29748. - - 27 Jul 2003; Martin Schlemmer <azarah@gentoo.org> libsandbox.c : - Fix canonicalize() to ignore calls with path = "". - - 27 Jul 2003; Martin Schlemmer <azarah@gentoo.org> getcwd.c, libsandbox.c, - sandbox_futils.c, canonicalize.c : - Once again coreutils fails, as my systems had 2.5 kernel, the getcwd system - call handled strings larger than PATH_MAX (bug #21766). It however does not - work the same on 2.4 kernels. - - To fix, I added the posix implementation of getcwd() (from glibc cvs) that - do not need the system call. We use the default getcwd() function via a - wrapper (egetcwd), and then lstat the returned path. If lstat fails, it - means the current directory was removed, OR that the the system call for - getcwd failed (curious is that it do not fail and return NULL or set - errno, but rather just truncate the retured directory - usually from the - start), and if so, we use the generic getcwd() function (__egetcwd). Note - that we do not use the generic version all the time, as it calls lstat() - a great number of times, and performance degrade much. - - 29 Jun 2003; Martin Schlemmer <azarah@gentoo.org> create-localdecls, - libsandbox.c : - Make sure SB_PATH_MAX will not wrap. Fix two possible memory leaks. - - 22 Jun 2003; Martin Schlemmer <azarah@gentoo.org> libsandbox.c, canonicalize.c - create-localdecls : - When checking path names of files accessed, we need to canonicalize it, else - it may be a symlink in a 'write allowed' directory pointing to a file in a - directory we should not have write access to. - - With something like coreutils-5.0, we have two problems: - 1) One of the tests checks if getcwd() can return a path longer than - PATH_MAX. This test then tries to create a dir which even while - created local (mkdir("conftest2")), it ends up being resolved with - a name that is much larger than PATH_MAX. The problem now is that - canonicalize() have undefined behaviour when the path was too long - (returned wrongly truncated paths, etc), and pass the wrong path to - before_syscall() (causing the bogus sandbox violations). - 2) The ecanonicalize() function we used, along with the canonicalize() - function did not support longer than PATH_MAX. This is partly a - cause for 1), but the error checking (rather lack of it) of calls - to erealpath() in canonicalize() was the prime reason for 1). - - As we do not use this canonicalized name to call the function, we resolve this - by fixing canonicalize() to do better error checking, and ecanonicalize() as - well as all functions in libsandbox.c to use a PATH_MAX of 'PATH_MAX * 2'. - While they will resolve paths properly now, and can check if a write/read is - allowed, the functions called from the sandboxed environment will still work - as expected. - - This should resolve bug #21766. - - 06 Apr 2003; Martin Schlemmer <azarah@gentoo.org> libsandbox.c : - For some reason sandbox fails with a 'open_wr' if you run 'locale -a' under - it (bug #16298). - - Problem is that for some reason locale fopen's locale.alias with mode "rm". - - ------------------------------------------------------- - nosferatu root # grep fopen locale.log - fopen("/usr/share/locale/locale.alias", "rm"ACCESS DENIED open_wr: /usr/share/locale/locale.alias - nosferatu root # - -------------------------------------------------------- - - I checked the source of locale, but it have fopen with mode 'r', so - not sure where the "rm" mode comes from. Anyhow, changed the check in - before_syscall_open_char() to also see mode "rm" as readonly. - - 23 Feb 2003; Martin Schlemmer <azarah@gentoo.org> create-localdecls : - - Add glibc-2.3 support. - - 22 Feb 2003; Martin Schlemmer <azarah@gentoo.org> sandbox.c : - - Some /etc/ld.so.preload fixes. Just changed the #if defines to cover all - operations releated to preload, as well as only try to modify ld.so.preload - if we can. Also modify to write the pid to /tmp/sandboxpids.tmp even when - not using ld.so.preload. Fix to not write this instance of sandbox's pid - to /tmp/sandboxpids.tmp on exit if this is not the last sandbox running. - - 22 Feb 2003; Nicholas Jones <carpaski@gentoo.org> Makefile : - - Changed the LD to CC for hppa. - - 22 Feb 2003; Nicholas Jones <carpaski@gentoo.org> create-localdecls : - - Killed the previous changes I made. - - 17 Feb 2003; Nicholas Jones <carpaski@gentoo.org> create-localdecls : - - Added parisc to BROKEN_RTLD_ARCHLIST to see if it we can fix the relocation probs. - - 09 Jan 2003; J Robert Ray <jrray@gentoo.org> sandbox.c : - - Don't segfault if $HOME isn't set, set $HOME to "/" instead. Fixes bug 10868. - - 16 Dec 2002; Martin Schlemmer <azarah@gentoo.org> create-localdecls : - - Fix memory leak for mips, bug #12236. Thanks to Torgeir Hansen <torgeir@trenger.ro> - for this fix. - - 4 Dec 2002; J Robert Ray <jrray@gentoo.org> sandbox.h sandbox_futils.c : - - sandbox_futils defined a dirname() function that was masking the same - function in glibc and was broken (e.g.: SANDBOX_DIR was being set to - '/usr/lib/portage/bi/'). Fixed function to return expected results and - renamed it to sb_dirname() to no longer mask the glibc function. Closes bug - 11231. - - 4 Dec 2002; Martin Schlemmer <azarah@gentoo.org> : - - Fix a segfault in libsandbox.c if canonicalize() was called with - first parameter = NULL. - - 1 Sep 2002; Martin Schlemmer <azarah@gentoo.org> : - - Fix my braindead 'return 1;' in a void function. Updated sandbox.c, - cleanup() for this. - - Change cleanup() in sandbox.c not to exit with fail status if - the pidsfile is missing. We really should still display sandbox - violations if they occured. - - 31 Aug 2002; Martin Schlemmer <azarah@gentoo.org> : - - Update cleanup() in sandbox.c to remove the PIDSFILE if this is - the last sandbox running. - - 25 Aug 2002; Martin Schlemmer <azarah@gentoo.org> : - - Major cleanups to mainly libsandbox.c again. - - 22 Aug 2002; Martin Schlemmer <azarah@gentoo.org> : - - Add copyrights to sandbox.h and sandbox_futils.h. If wrong, the - parties involved should please contact me so that we can fix it. - - Add opendir wrapper to libsandbox.c. - - 21 Aug 2002; Martin Schlemmer <azarah@gentoo.org> : - - Do some more cleanups to ecanonicalize(), as it dropped filenames in - rare cases (after my symlink cleanups), and caused glibc to bork. - These fixes went into canonicalize.c. - - 20 Aug 2002; Martin Schlemmer <azarah@gentoo.org> : - - Fix spawn_shell() and main() in sandbox.c to properly return fail - status. - - 19 Aug 2002; Martin Schlemmer <azarah@gentoo.org> : - - The new canonicalize() function in libsandbox.c also resolved symlinks, - which caused on cleaning sandbox errors if the symlink pointed to a - file in the live root. Ripped out canonicalize() and realpath() from - glibc; removed the symlink stuff, and changed them to ecanonicalize() - and erealpath(). - - 18 Aug 2002; Martin Schlemmer <azarah@gentoo.org> : - - Ripped out all the wrappers, and implemented those of InstallWatch. - Losts of cleanups and bugfixes. Implement a execve that forces - $LIBSANDBOX in $LD_PRELOAD. We can now thus do away with the feared - /etc/ld.so.preload (*g*) ... Made the needed changes to sandbox.c, - sandbox.h and sandbox_futils.c. Rewrote the Makefile for most - parts; it now have an install target. - - Reformat the whole thing to look somewhat like the reworked sandbox.c - and new sandbox.h and sandbox_futils.c from: - - Brad House <brad@mainstreetsoftworks.com>. - - Additional Copyrights now due to the InstallWatch code: - - Copyright (C) 1998-9 Pancrazio `Ezio' de Mauro <p@demauro.net> - diff --git a/src/sandbox-1.1/Makefile b/src/sandbox-1.1/Makefile deleted file mode 100644 index add08fc23..000000000 --- a/src/sandbox-1.1/Makefile +++ /dev/null @@ -1,81 +0,0 @@ -# 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> -# -# Modified 15 Apr 2002 Jon Nelson <jnelson@gentoo.org> -# Clean up Makefile somewhat, and use make's implicit rules -# -# Modified 19 Aug 2002; Martin Schlemmer <azarah@gentoo.org> -# Major rewrite to support new stuff -# -# Indent: indent -kr -i2 -ts2 -sob -l80 -ss -bs -psl -# -# $Id: /var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/Makefile,v 1.7.2.2 2004/11/29 08:41:28 carpaski Exp $ - -CC ?= gcc -LD ?= ld -CFLAGS = -ARCH_CFLAGS = -OBJ_CFLAGS = -D_GNU_SOURCE -DPIC -fPIC -D_REENTRANT -LIBS = -LDFLAGS = -DESTDIR = - -HAVE_64BIT_ARCH = - -ifneq ($(HAVE_64BIT_ARCH),) - TARGETS = libsandbox.so libsandbox32.so sandbox - ARCH_CFLAGS += -m64 - OBJ_CFLAGS += -DSB_HAVE_64BIT_ARCH -else - TARGETS = libsandbox.so sandbox -endif - -all: $(TARGETS) - -sandbox: sandbox.o sandbox_futils.o getcwd.c - $(CC) $(CFLAGS) $(ARCH_CFLAGS) $(OBJ_CFLAGS) -Wall $^ -ldl -lc -o $@ - -sandbox.o: sandbox.c sandbox.h - $(CC) $(CFLAGS) $(ARCH_CFLAGS) $(OBJ_CFLAGS) -Wall -c sandbox.c -o $@ - -sandbox_futils.o: localdecls.h sandbox_futils.c sandbox.h - $(CC) $(CFLAGS) $(ARCH_CFLAGS) $(OBJ_CFLAGS) -Wall -c sandbox_futils.c -o $@ - -libsandbox.so: libsandbox.o sandbox_futils.o - $(CC) $^ -shared $(ARCH_CFLAGS) -fPIC -ldl -lc -nostdlib -lgcc -o $@ - -libsandbox.o: localdecls.h libsandbox.c canonicalize.c getcwd.c - $(CC) $(CFLAGS) $(ARCH_CFLAGS) $(OBJ_CFLAGS) -Wall -c libsandbox.c - -sandbox_futils32.o: sandbox_futils.c sandbox.h - $(CC) $(CFLAGS) -m32 $(OBJ_CFLAGS) -Wall -c sandbox_futils.c -o $@ - -libsandbox32.so: libsandbox32.o sandbox_futils32.o - $(CC) $^ -shared -m32 -fPIC -ldl -lc -nostdlib -lgcc -o $@ - -libsandbox32.o: libsandbox.c localdecls.h canonicalize.c getcwd.c - $(CC) $(CFLAGS) -m32 $(OBJ_CFLAGS) -Wall -c libsandbox.c -o $@ - -localdecls.h: create-localdecls libctest.c - ./create-localdecls - - -install: all - install -d -m 0755 $(DESTDIR)/lib - $(if $(HAVE_64BIT_ARCH),install -d -m 0755 $(DESTDIR)/lib32) - install -d -m 0755 $(DESTDIR)/usr/lib/portage/bin - install -d -m 0755 $(DESTDIR)/usr/lib/portage/lib - install -m 0755 libsandbox.so $(DESTDIR)/lib - $(if $(HAVE_64BIT_ARCH),install -m 0755 libsandbox32.so $(DESTDIR)/lib32/libsandbox.so) - install -m 0755 sandbox $(DESTDIR)/usr/lib/portage/bin - install -m 0644 sandbox.bashrc $(DESTDIR)/usr/lib/portage/lib - - -clean: - rm -f $(TARGETS) - rm -f *.o *~ core - rm -f localdecls.h - - -# vim:expandtab noai:cindent ai diff --git a/src/sandbox-1.1/canonicalize.c b/src/sandbox-1.1/canonicalize.c deleted file mode 100644 index f1300e204..000000000 --- a/src/sandbox-1.1/canonicalize.c +++ /dev/null @@ -1,173 +0,0 @@ -/* Return the canonical absolute name of a given file. - Copyright (C) 1996-2001, 2002 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* - * $Id: /var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/canonicalize.c,v 1.5.2.1 2004/10/22 16:53:30 carpaski Exp $ - */ - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <limits.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <errno.h> -#include <stddef.h> - -#ifndef __set_errno -# define __set_errno(val) errno = (val) -#endif - -/* Return the canonical absolute name of file NAME. A canonical name - does not contain any `.', `..' components nor any repeated path - separators ('/') or symlinks. All path components must exist. If - RESOLVED is null, the result is malloc'd; otherwise, if the - canonical name is SB_PATH_MAX chars or more, returns null with `errno' - set to ENAMETOOLONG; if the name fits in fewer than SB_PATH_MAX chars, - returns the name in RESOLVED. If the name cannot be resolved and - RESOLVED is non-NULL, it contains the path of the first component - that cannot be resolved. If the path can be resolved, RESOLVED - holds the same value as the value returned. */ - -/* Modified: 19 Aug 2002; Martin Schlemmer <azarah@gentoo.org> - * - * Cleaned up unneeded stuff, and change so that it will not - * resolve symlinks. Also prepended a 'e' to functions that - * I did not rip out. - * - */ - -char * -erealpath(const char *name, char *resolved) -{ - char *rpath, *dest; - const char *start, *end, *rpath_limit; - long int path_max; - - if (name == NULL) { - /* As per Single Unix Specification V2 we must return an error if - either parameter is a null pointer. We extend this to allow - the RESOLVED parameter to be NULL in case the we are expected to - allocate the room for the return value. */ - __set_errno(EINVAL); - return NULL; - } - - if (name[0] == '\0') { - /* As per Single Unix Specification V2 we must return an error if - the name argument points to an empty string. */ - __set_errno(ENOENT); - return NULL; - } -#ifdef SB_PATH_MAX - path_max = SB_PATH_MAX; -#else - path_max = pathconf(name, _PC_PATH_MAX); - if (path_max <= 0) - path_max = 1024; -#endif - - if (resolved == NULL) { - rpath = malloc(path_max); - if (rpath == NULL) - return NULL; - } else - rpath = resolved; - rpath_limit = rpath + path_max; - - if (name[0] != '/') { - if (!egetcwd(rpath, path_max)) { - rpath[0] = '\0'; - goto error; - } - dest = strchr(rpath, '\0'); - } else { - rpath[0] = '/'; - dest = rpath + 1; - } - - for (start = end = name; *start; start = end) { - /* Skip sequence of multiple path-separators. */ - while (*start == '/') - ++start; - - /* Find end of path component. */ - for (end = start; *end && *end != '/'; ++end) - /* Nothing. */ ; - - if (end - start == 0) - break; - else if (end - start == 1 && start[0] == '.') - /* nothing */ ; - else if (end - start == 2 && start[0] == '.' && start[1] == '.') { - /* Back up to previous component, ignore if at root already. */ - if (dest > rpath + 1) - while ((--dest)[-1] != '/') ; - } else { - size_t new_size; - - if (dest[-1] != '/') - *dest++ = '/'; - - if (dest + (end - start) >= rpath_limit) { - ptrdiff_t dest_offset = dest - rpath; - char *new_rpath; - - if (resolved) { - __set_errno(ENAMETOOLONG); - if (dest > rpath + 1) - dest--; - *dest = '\0'; - goto error; - } - new_size = rpath_limit - rpath; - if (end - start + 1 > path_max) - new_size += end - start + 1; - else - new_size += path_max; - new_rpath = (char *) realloc(rpath, new_size); - if (new_rpath == NULL) - goto error; - rpath = new_rpath; - rpath_limit = rpath + new_size; - - dest = rpath + dest_offset; - } - - dest = __mempcpy(dest, start, end - start); - *dest = '\0'; - } - } -#if 1 - if (dest > rpath + 1 && dest[-1] == '/') - --dest; -#endif - *dest = '\0'; - - return resolved ? memcpy(resolved, rpath, dest - rpath + 1) : rpath; - -error: - if (resolved) - strcpy(resolved, rpath); - else - free(rpath); - return NULL; -} - -// vim:expandtab noai:cindent ai diff --git a/src/sandbox-1.1/create-localdecls b/src/sandbox-1.1/create-localdecls deleted file mode 100755 index ec7a3a786..000000000 --- a/src/sandbox-1.1/create-localdecls +++ /dev/null @@ -1,115 +0,0 @@ -#!/bin/sh - -# This is a quick'n'dirty hack to make the program behave correctly -# under different systems. -# Example: -# when using libc5, (f)trucate's offset argument type is size_t with -# libc5, but it's off_t with libc6 (glibc2). -# -# Uhm... time to learn GNU autoconf :-) -# -# $Id: /var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/create-localdecls,v 1.11.2.1 2004/10/22 16:53:30 carpaski Exp $ - -OUTFILE='localdecls.h' - -# if your arch needs to dlopen() glibc, add it here separated by space :] -BROKEN_RTLD_ARCHLIST="mips" - -echo '/* This file is automatically generated *' > $OUTFILE -echo ' * Modify create-localdecls instead of this */' >> $OUTFILE -echo >> $OUTFILE -echo '#ifndef __LOCALDECLS_H_' >> $OUTFILE -echo '#define __LOCALDECLS_H_' >> $OUTFILE -echo >> $OUTFILE - -### -### -### - -echo -n 'Checking truncate argument type... ' -if grep -q 'truncate.*size_t' /usr/include/unistd.h ; then - echo 'size_t' - echo '#define TRUNCATE_T size_t' >> $OUTFILE -else - echo 'off_t' # At least, I HOPE it's off_t :-) - echo '#define TRUNCATE_T off_t' >> $OUTFILE -fi - -### -### -### - -echo -n 'Checking libc version... ' -gcc -Wall -o libctest libctest.c -VERSION=`ldd libctest | grep libc\\.so | grep -v 'ld-uClibc' | awk '{print $1}'` - -echo $VERSION -echo "#define LIBC_VERSION \"$VERSION\"" >> $OUTFILE -if test "$VERSION" = 'libc.so.5' ; then - echo '#define BROKEN_RTLD_NEXT' >> $OUTFILE - echo '#define LIBC 5' >> $OUTFILE -else - # for the arch's that need to dlopen() libc to fetch real funcs! - # 16.12.02 -Torgeir Hansen <torgeir@trenger.ro> - MYARCH=`/bin/uname -m` - for x in $BROKEN_RTLD_ARCHLIST; do - if [ $x = $MYARCH ]; then - echo '#define BROKEN_RTLD_NEXT' >> $OUTFILE - fi - done - -fi - -if test "$VERSION" = 'libc.so.6' ; then - echo -n 'Checking glibc subversion...' - tmp="$(ldd libctest 2>/dev/null | grep libc.so 2>/dev/null | head -n 1)" - LibcPath=`expr "$tmp" : '[^/]*\(/[^ ]*\)'` - tmp="`strings $LibcPath | grep -i 'c library'`" - OsLibcMajor=`expr "$tmp" : '.* \([0-9][0-9]*\)'` - OsLibcMinor=`expr "$tmp" : '.* [0-9][0-9]*\.\([0-9][0-9]*\)'` - echo " ${OsLibcMajor}.${OsLibcMinor}" - case "$OsLibcMajor" in - 2) - # 2 is the glibc version - case "$OsLibcMinor" in - 0) - echo '#define GLIBC_MINOR 0' >> $OUTFILE - SUBVERSION='glibc-2.0' ;; - 1) - echo '#define GLIBC_MINOR 1' >> $OUTFILE - SUBVERSION='glibc-2.1' ;; - 2) - echo '#define GLIBC_MINOR 2' >> $OUTFILE - SUBVERSION='glibc-2.2' ;; - 3) - echo '#define GLIBC_MINOR 3' >> $OUTFILE - SUBVERSION='glibc-2.3' ;; - *) - echo 'Treated as glibc >= 2.1 (finger crossed)' - echo '#define GLIBC_MINOR 1' >> $OUTFILE - SUBVERSION='glibc-2.1' ;; - esac - ;; - esac -fi - -rm libctest - -echo ' -#ifdef PATH_MAX -# define SB_PATH_MAX PATH_MAX * 2 -# if (SB_PATH_MAX >= INT_MAX) || (SB_PATH_MAX < PATH_MAX) -# undef SB_PATH_MAX -# define SB_PATH_MAX PATH_MAX + 25 -# if (SB_PATH_MAX >= INT_MAX) || (SB_PATH_MAX < PATH_MAX) -# error SB_PATH_MAX too big! -# endif -# endif -#else -# error PATH_MAX not defined! -#endif' >> $OUTFILE - -echo >> $OUTFILE -echo '#endif' >> $OUTFILE -echo - diff --git a/src/sandbox-1.1/getcwd.c b/src/sandbox-1.1/getcwd.c deleted file mode 100644 index 07c72970d..000000000 --- a/src/sandbox-1.1/getcwd.c +++ /dev/null @@ -1,511 +0,0 @@ -/* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* Wants: - AC_STDC_HEADERS - AC_DIR_HEADER - AC_UNISTD_H - AC_MEMORY_H - AC_CONST - AC_ALLOCA - */ - -/* - * $Id: /var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/getcwd.c,v 1.1.2.1 2004/10/22 16:53:30 carpaski Exp $ - */ - -/* Modified: 26 July 2003; Martin Schlemmer <azarah@gentoo.org> - * - * Cleaned up unneeded stuff. Add a wrapper to try and detect when - * we have a kernel whose getcwd system call do not handle directory - * names longer than PATH_MAX, and if so, use our generic version. - * To work truly with > PATH_MAX lengh CWDs, I had to increase the - * size of the dots[] array. Also prepended a 'e' to functions that - * I did not rip out. - * - */ - -/* AIX requires this to be the first thing in the file. */ -#if defined _AIX && !defined __GNUC__ -#pragma alloca -#endif - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef STDC_HEADERS -# include <stddef.h> -#endif - -#if !defined __GNU_LIBRARY__ && !defined STDC_HEADERS -extern int errno; -#endif -#ifndef __set_errno -# define __set_errno(val) errno = (val) -#endif - -#ifndef NULL -# define NULL 0 -#endif - -#if defined USGr3 && !defined DIRENT -# define DIRENT -#endif /* USGr3 */ -#if defined Xenix && !defined SYSNDIR -# define SYSNDIR -#endif /* Xenix */ - -#if defined POSIX || defined DIRENT || defined __GNU_LIBRARY__ -# include <dirent.h> -# ifndef __GNU_LIBRARY__ -# define D_NAMLEN(d) strlen((d)->d_name) -# else -# define HAVE_D_NAMLEN -# define D_NAMLEN(d) ((d)->d_namlen) -# endif -#else /* not POSIX or DIRENT */ -# define dirent direct -# define D_NAMLEN(d) ((d)->d_namlen) -# define HAVE_D_NAMLEN -# if defined USG && !defined sgi -# if defined SYSNDIR -# include <sys/ndir.h> -# else /* Not SYSNDIR */ -# include "ndir.h" -# endif /* SYSNDIR */ -# else /* not USG */ -# include <sys/dir.h> -# endif /* USG */ -#endif /* POSIX or DIRENT or __GNU_LIBRARY__ */ - -#if defined HAVE_UNISTD_H || defined __GNU_LIBRARY__ -# include <unistd.h> -#endif - -#if defined STDC_HEADERS || defined __GNU_LIBRARY__ || defined POSIX -# include <stdlib.h> -# include <string.h> -# define ANSI_STRING -#else /* No standard headers. */ - -# ifdef USG - -# include <string.h> -# ifdef NEED_MEMORY_H -# include <memory.h> -# endif -# define ANSI_STRING - -# else /* Not USG. */ - -# ifdef NeXT - -# include <string.h> - -# else /* Not NeXT. */ - -# include <strings.h> - -# ifndef bcmp -extern int bcmp(); -# endif -# ifndef bzero -extern void bzero(); -# endif -# ifndef bcopy -extern void bcopy(); -# endif - -# endif /* NeXT. */ - -# endif /* USG. */ - -extern char *malloc(), *realloc(); -extern void free(); - -#endif /* Standard headers. */ - -#ifndef ANSI_STRING -# define memcpy(d, s, n) bcopy((s), (d), (n)) -# define memmove memcpy -#endif /* Not ANSI_STRING. */ - -#ifndef MAX -# define MAX(a, b) ((a) < (b) ? (b) : (a)) -#endif - -#ifdef _LIBC -# ifndef mempcpy -# define mempcpy __mempcpy -# endif -# define HAVE_MEMPCPY 1 -#endif - -#if !defined __alloca && !defined __GNU_LIBRARY__ - -# ifdef __GNUC__ -# undef alloca -# define alloca(n) __builtin_alloca (n) -# else /* Not GCC. */ -# if defined sparc || defined HAVE_ALLOCA_H -# include <alloca.h> -# else /* Not sparc or HAVE_ALLOCA_H. */ -# ifndef _AIX -extern char *alloca(); -# endif /* Not _AIX. */ -# endif /* sparc or HAVE_ALLOCA_H. */ -# endif /* GCC. */ - -# define __alloca alloca - -#endif - -#if defined HAVE_LIMITS_H || defined STDC_HEADERS || defined __GNU_LIBRARY__ -# include <limits.h> -#else -# include <sys/param.h> -#endif - -#ifndef PATH_MAX -# ifdef MAXPATHLEN -# define PATH_MAX MAXPATHLEN -# else -# define PATH_MAX 1024 -# endif -#endif - -#if !defined STDC_HEADERS && !defined __GNU_LIBRARY__ -# undef size_t -# define size_t unsigned int -#endif - -#if !__STDC__ && !defined const -# define const -#endif - -#ifndef __GNU_LIBRARY__ -# define __lstat stat -#endif - -#ifndef _LIBC -# define __getcwd getcwd -#endif - -#ifndef GETCWD_RETURN_TYPE -# define GETCWD_RETURN_TYPE char * -#endif - -#ifndef SB_PATH_MAX -# include "localdecls.h" -# define OUTSIDE_LIBSANDBOX -#endif - -#ifndef __LIBC -# define __lstat lstat -# define __readdir readdir -# define __closedir closedir -#endif - -/* Get the pathname of the current working directory, and put it in SIZE - bytes of BUF. Returns NULL if the directory couldn't be determined or - SIZE was too small. If successful, returns BUF. In GNU, if BUF is - NULL, an array is allocated with `malloc'; the array is SIZE bytes long, - unless SIZE == 0, in which case it is as big as necessary. */ - -GETCWD_RETURN_TYPE -__egetcwd(buf, size) -char *buf; -size_t size; -{ - static const char dots[] - = "../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../.."; - const char *dotp = &dots[sizeof (dots)]; - const char *dotlist = dots; - size_t dotsize = sizeof (dots) - 1; - dev_t rootdev, thisdev; - ino_t rootino, thisino; - char *path; - register char *pathp; - struct stat st; - int prev_errno = errno; - size_t allocated = size; - - if (size == 0) { - if (buf != NULL) { - __set_errno(EINVAL); - return NULL; - } - - allocated = SB_PATH_MAX + 1; - } - - if (buf != NULL) - path = buf; - else { - path = malloc(allocated); - if (path == NULL) - return NULL; - } - - pathp = path + allocated; - *--pathp = '\0'; - - if (__lstat(".", &st) < 0) - goto lose2; - thisdev = st.st_dev; - thisino = st.st_ino; - - if (__lstat("/", &st) < 0) - goto lose2; - rootdev = st.st_dev; - rootino = st.st_ino; - - while (!(thisdev == rootdev && thisino == rootino)) { - register DIR *dirstream; - struct dirent *d; - dev_t dotdev; - ino_t dotino; - char mount_point; - - /* Look at the parent directory. */ - if (dotp == dotlist) { - /* My, what a deep directory tree you have, Grandma. */ - char *new; - if (dotlist == dots) { - new = malloc(dotsize * 2 + 1); - if (new == NULL) - goto lose; -#ifdef HAVE_MEMPCPY - dotp = mempcpy(new, dots, dotsize); -#else - memcpy(new, dots, dotsize); - dotp = &new[dotsize]; -#endif - } else { - new = realloc((__ptr_t) dotlist, dotsize * 2 + 1); - if (new == NULL) - goto lose; - dotp = &new[dotsize]; - } -#ifdef HAVE_MEMPCPY - *((char *) mempcpy((char *) dotp, new, dotsize)) = '\0'; - dotsize *= 2; -#else - memcpy((char *) dotp, new, dotsize); - dotsize *= 2; - new[dotsize] = '\0'; -#endif - dotlist = new; - } - - dotp -= 3; - - /* Figure out if this directory is a mount point. */ - if (__lstat(dotp, &st) < 0) - goto lose; - dotdev = st.st_dev; - dotino = st.st_ino; - mount_point = dotdev != thisdev; - - /* Search for the last directory. */ -#ifdef OUTSIDE_LIBSANDBOX - dirstream = opendir(dotp); -#else - dirstream = true_opendir(dotp); -#endif - if (dirstream == NULL) - goto lose; - /* Clear errno to distinguish EOF from error if readdir returns - NULL. */ - __set_errno(0); - while ((d = __readdir(dirstream)) != NULL) { - if (d->d_name[0] == '.' && - (d->d_name[1] == '\0' - || (d->d_name[1] == '.' && d->d_name[2] == '\0'))) - continue; - if (mount_point || (ino_t) d->d_ino == thisino) { - char name[dotlist + dotsize - dotp + 1 + _D_ALLOC_NAMLEN(d)]; -#ifdef HAVE_MEMPCPY - char *tmp = mempcpy(name, dotp, - dotlist + dotsize - dotp); - *tmp++ = '/'; - strcpy(tmp, d->d_name); -#else - memcpy(name, dotp, dotlist + dotsize - dotp); - name[dotlist + dotsize - dotp] = '/'; - strcpy(&name[dotlist + dotsize - dotp + 1], d->d_name); -#endif - /* We don't fail here if we cannot stat() a directory entry. - This can happen when (network) filesystems fail. If this - entry is in fact the one we are looking for we will find - out soon as we reach the end of the directory without - having found anything. */ - if (__lstat(name, &st) >= 0 && st.st_dev == thisdev - && st.st_ino == thisino) - break; - } - } - if (d == NULL) { - int save = errno; - (void) __closedir(dirstream); - if (save == 0) - /* EOF on dirstream, which means that the current directory - has been removed. */ - save = ENOENT; - __set_errno(save); - goto lose; - } else { - size_t namlen = _D_EXACT_NAMLEN(d); - - if ((size_t) (pathp - path) <= namlen) { - if (size != 0) { - (void) __closedir(dirstream); - __set_errno(ERANGE); - goto lose; - } else { - char *tmp; - size_t oldsize = allocated; - - allocated = 2 * MAX(allocated, namlen); - tmp = realloc(path, allocated); - if (tmp == NULL) { - (void) __closedir(dirstream); - __set_errno(ENOMEM); /* closedir might have changed it. */ - goto lose; - } - - /* Move current contents up to the end of the buffer. - This is guaranteed to be non-overlapping. */ - pathp = - memcpy(tmp + allocated - - (path + oldsize - pathp), - tmp + (pathp - path), path + oldsize - pathp); - path = tmp; - } - } - pathp -= namlen; - (void) memcpy(pathp, d->d_name, namlen); - *--pathp = '/'; - (void) __closedir(dirstream); - } - - thisdev = dotdev; - thisino = dotino; - } - - if (pathp == &path[allocated - 1]) - *--pathp = '/'; - - if (dotlist != dots) - free((__ptr_t) dotlist); - - memmove(path, pathp, path + allocated - pathp); - - /* Restore errno on successful return. */ - __set_errno(prev_errno); - - return path; - -lose: - if (dotlist != dots) - free((__ptr_t) dotlist); -lose2: - if (buf == NULL) - free(path); - return NULL; -} - -GETCWD_RETURN_TYPE -egetcwd(buf, size) -char *buf; -size_t size; -{ - struct stat st; - char *tmpbuf; - - __set_errno(0); - tmpbuf = getcwd(buf, size); - - if (tmpbuf) { - __lstat(buf, &st); - } else { - return tmpbuf; - } - - if (errno) { - /* If lstat() failed with eerror = ENOENT, then its - * possible that we are running on an older kernel, - * so use our generic version which *should* not fail. - */ - if (errno == ENOENT) { - return __egetcwd(buf, size); - } else { - return tmpbuf; - } - } - - return tmpbuf; -} - -// vim:expandtab noai:cindent ai diff --git a/src/sandbox-1.1/libctest.c b/src/sandbox-1.1/libctest.c deleted file mode 100644 index 5365a20c6..000000000 --- a/src/sandbox-1.1/libctest.c +++ /dev/null @@ -1,7 +0,0 @@ -/* Dummy program to check your libc version */ - -int -main(void) -{ - return 0; -} diff --git a/src/sandbox-1.1/libsandbox.c b/src/sandbox-1.1/libsandbox.c deleted file mode 100644 index 8afbac71e..000000000 --- a/src/sandbox-1.1/libsandbox.c +++ /dev/null @@ -1,1383 +0,0 @@ -/* - * Path sandbox for the gentoo linux portage package system, initially - * based on the ROCK Linux Wrapper for getting a list of created files - * - * to integrate with bash, bash should have been built like this - * - * ./configure --prefix=<prefix> --host=<host> --without-gnu-malloc - * - * it's very important that the --enable-static-link option is NOT specified - * - * 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> - * - * Post Bevin leaving Gentoo ranks: - * -------------------------------- - * Ripped out all the wrappers, and implemented those of InstallWatch. - * Losts of cleanups and bugfixes. Implement a execve that forces $LIBSANDBOX - * in $LD_PRELOAD. Reformat the whole thing to look somewhat like the reworked - * sandbox.c from Brad House <brad@mainstreetsoftworks.com>. - * - * Martin Schlemmer <azarah@gentoo.org> (18 Aug 2002) - * - * Partly Copyright (C) 1998-9 Pancrazio `Ezio' de Mauro <p@demauro.net>, - * as some of the InstallWatch code was used. - * - * - * $Id: /var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/libsandbox.c,v 1.22.2.3 2004/12/01 22:14:09 carpaski Exp $ - * - */ - -/* Uncomment below to enable wrapping of mknod(). - * This is broken currently. */ -/* #define WRAP_MKNOD 1 */ - -/* Uncomment below to enable the use of strtok_r(). */ -#define REENTRANT_STRTOK 1 - -/* Uncomment below to enable memory debugging. */ -/* #define SB_MEM_DEBUG 1 */ - -#define open xxx_open -#define open64 xxx_open64 - -/* Wrapping mknod, do not have any effect, and - * wrapping __xmknod causes calls to it to segfault - */ -#ifdef WRAP_MKNOD -# define __xmknod xxx___xmknod -#endif - -#include <dirent.h> -#include <dlfcn.h> -#include <errno.h> -#include <fcntl.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/param.h> -#include <unistd.h> -#include <utime.h> - -#ifdef SB_MEM_DEBUG -# include <mcheck.h> -#endif - -#ifdef WRAP_MKNOD -# undef __xmknod -#endif - -#undef open -#undef open64 - -#include "localdecls.h" -#include "sandbox.h" - -/* Macros to check if a function should be executed */ -#define FUNCTION_SANDBOX_SAFE(func, path) \ - ((0 == is_sandbox_on()) || (1 == before_syscall(func, path))) - -#define FUNCTION_SANDBOX_SAFE_INT(func, path, flags) \ - ((0 == is_sandbox_on()) || (1 == before_syscall_open_int(func, path, flags))) - -#define FUNCTION_SANDBOX_SAFE_CHAR(func, path, mode) \ - ((0 == is_sandbox_on()) || (1 == before_syscall_open_char(func, path, mode))) - -/* Macro to check if a wrapper is defined, if not - * then try to resolve it again. */ -#define check_dlsym(name) \ -{ \ - int old_errno=errno; \ - if (!true_ ## name) true_ ## name=get_dlsym(#name); \ - errno=old_errno; \ -} - -/* Macro to check if we could canonicalize a path. It returns an integer on - * failure. */ -#define canonicalize_int(path, resolved_path) \ -{ \ - if (0 != canonicalize(path, resolved_path)) \ - return -1; \ -} - -/* Macro to check if we could canonicalize a path. It returns a NULL pointer on - * failure. */ -#define canonicalize_ptr(path, resolved_path) \ -{ \ - if (0 != canonicalize(path, resolved_path)) \ - return NULL; \ -} - -static char sandbox_lib[255]; -//static char sandbox_pids_file[255]; -static char *sandbox_pids_file; - -typedef struct { - int show_access_violation; - char **deny_prefixes; - int num_deny_prefixes; - char **read_prefixes; - int num_read_prefixes; - char **write_prefixes; - int num_write_prefixes; - char **predict_prefixes; - int num_predict_prefixes; - char **write_denied_prefixes; - int num_write_denied_prefixes; -} sbcontext_t; - -/* glibc modified realpath() functions */ -char *erealpath(const char *name, char *resolved); -/* glibc modified getcwd() functions */ -char *egetcwd(char *, size_t); - -static void init_wrappers(void); -static void *get_dlsym(const char *); -static int canonicalize(const char *, char *); -static int check_access(sbcontext_t *, const char *, const char *); -static int check_syscall(sbcontext_t *, const char *, const char *); -static int before_syscall(const char *, const char *); -static int before_syscall_open_int(const char *, const char *, int); -static int before_syscall_open_char(const char *, const char *, const char *); -static void clean_env_entries(char ***, int *); -static void init_context(sbcontext_t *); -static void init_env_entries(char ***, int *, char *, int); -static char *filter_path(const char *); -static int is_sandbox_on(); -static int is_sandbox_pid(); - -/* Wrapped functions */ - -extern int chmod(const char *, mode_t); -static int (*true_chmod) (const char *, mode_t); -extern int chown(const char *, uid_t, gid_t); -static int (*true_chown) (const char *, uid_t, gid_t); -extern int creat(const char *, mode_t); -static int (*true_creat) (const char *, mode_t); -extern FILE *fopen(const char *, const char *); -static FILE *(*true_fopen) (const char *, const char *); -extern int lchown(const char *, uid_t, gid_t); -static int (*true_lchown) (const char *, uid_t, gid_t); -extern int link(const char *, const char *); -static int (*true_link) (const char *, const char *); -extern int mkdir(const char *, mode_t); -static int (*true_mkdir) (const char *, mode_t); -extern DIR *opendir(const char *); -static DIR *(*true_opendir) (const char *); -#ifdef WRAP_MKNOD -extern int __xmknod(const char *, mode_t, dev_t); -static int (*true___xmknod) (const char *, mode_t, dev_t); -#endif -extern int open(const char *, int, ...); -static int (*true_open) (const char *, int, ...); -extern int rename(const char *, const char *); -static int (*true_rename) (const char *, const char *); -extern int rmdir(const char *); -static int (*true_rmdir) (const char *); -extern int symlink(const char *, const char *); -static int (*true_symlink) (const char *, const char *); -extern int truncate(const char *, TRUNCATE_T); -static int (*true_truncate) (const char *, TRUNCATE_T); -extern int unlink(const char *); -static int (*true_unlink) (const char *); - -#if (GLIBC_MINOR >= 1) - -extern int creat64(const char *, __mode_t); -static int (*true_creat64) (const char *, __mode_t); -extern FILE *fopen64(const char *, const char *); -static FILE *(*true_fopen64) (const char *, const char *); -extern int open64(const char *, int, ...); -static int (*true_open64) (const char *, int, ...); -extern int truncate64(const char *, __off64_t); -static int (*true_truncate64) (const char *, __off64_t); - -#endif - -extern int execve(const char *filename, char *const argv[], char *const envp[]); -static int (*true_execve) (const char *, char *const[], char *const[]); - -/* - * Initialize the shabang - */ - -static void -init_wrappers(void) -{ - void *libc_handle = NULL; - -#ifdef BROKEN_RTLD_NEXT -// printf ("RTLD_LAZY"); - libc_handle = dlopen(LIBC_VERSION, RTLD_LAZY); -#else -// printf ("RTLD_NEXT"); - libc_handle = RTLD_NEXT; -#endif - - true_chmod = dlsym(libc_handle, "chmod"); - true_chown = dlsym(libc_handle, "chown"); - true_creat = dlsym(libc_handle, "creat"); - true_fopen = dlsym(libc_handle, "fopen"); - true_lchown = dlsym(libc_handle, "lchown"); - true_link = dlsym(libc_handle, "link"); - true_mkdir = dlsym(libc_handle, "mkdir"); - true_opendir = dlsym(libc_handle, "opendir"); -#ifdef WRAP_MKNOD - true___xmknod = dlsym(libc_handle, "__xmknod"); -#endif - true_open = dlsym(libc_handle, "open"); - true_rename = dlsym(libc_handle, "rename"); - true_rmdir = dlsym(libc_handle, "rmdir"); - true_symlink = dlsym(libc_handle, "symlink"); - true_truncate = dlsym(libc_handle, "truncate"); - true_unlink = dlsym(libc_handle, "unlink"); - -#if (GLIBC_MINOR >= 1) - true_creat64 = dlsym(libc_handle, "creat64"); - true_fopen64 = dlsym(libc_handle, "fopen64"); - true_open64 = dlsym(libc_handle, "open64"); - true_truncate64 = dlsym(libc_handle, "truncate64"); -#endif - - true_execve = dlsym(libc_handle, "execve"); -} - -void -_fini(void) -{ - free(sandbox_pids_file); -} - -void -_init(void) -{ - int old_errno = errno; - char *tmp_string = NULL; - -#ifdef SB_MEM_DEBUG - mtrace(); -#endif - - init_wrappers(); - - /* Get the path and name to this library */ - tmp_string = get_sandbox_lib("/"); - strncpy(sandbox_lib, tmp_string, sizeof(sandbox_lib)-1); - if (tmp_string) - free(tmp_string); - tmp_string = NULL; - - /* Generate sandbox pids-file path */ - sandbox_pids_file = get_sandbox_pids_file(); - - errno = old_errno; -} - -static int -canonicalize(const char *path, char *resolved_path) -{ - int old_errno = errno; - char *retval; - - *resolved_path = '\0'; - - /* If path == NULL, return or we get a segfault */ - if (NULL == path) { - errno = EINVAL; - return -1; - } - - /* Do not try to resolve an empty path */ - if ('\0' == path[0]) { - errno = old_errno; - return 0; - } - - retval = erealpath(path, resolved_path); - - if ((!retval) && (path[0] != '/')) { - /* The path could not be canonicalized, append it - * to the current working directory if it was not - * an absolute path - */ - if (errno == ENAMETOOLONG) - return -1; - - egetcwd(resolved_path, SB_PATH_MAX - 2); - strcat(resolved_path, "/"); - strncat(resolved_path, path, SB_PATH_MAX - 1); - - if (!erealpath(resolved_path, resolved_path)) { - if (errno == ENAMETOOLONG) { - /* The resolved path is too long for the buffer to hold */ - return -1; - } else { - /* Whatever it resolved, is not a valid path */ - errno = ENOENT; - return -1; - } - } - - } else if ((!retval) && (path[0] == '/')) { - /* Whatever it resolved, is not a valid path */ - errno = ENOENT; - return -1; - } - - errno = old_errno; - return 0; -} - -static void * -get_dlsym(const char *symname) -{ - void *libc_handle = NULL; - void *symaddr = NULL; - -#ifdef BROKEN_RTLD_NEXT - libc_handle = dlopen(LIBC_VERSION, RTLD_LAZY); - if (!libc_handle) { - printf("libsandbox.so: Can't dlopen libc: %s\n", dlerror()); - abort(); - } -#else - libc_handle = RTLD_NEXT; -#endif - - symaddr = dlsym(libc_handle, symname); - if (!symaddr) { - printf("libsandbox.so: Can't resolve %s: %s\n", symname, dlerror()); - abort(); - } - - return symaddr; -} - -/* - * Wrapper Functions - */ - -int -chmod(const char *path, mode_t mode) -{ - int result = -1; - char canonic[SB_PATH_MAX]; - - canonicalize_int(path, canonic); - - if FUNCTION_SANDBOX_SAFE - ("chmod", canonic) { - check_dlsym(chmod); - result = true_chmod(path, mode); - } - - return result; -} - -int -chown(const char *path, uid_t owner, gid_t group) -{ - int result = -1; - char canonic[SB_PATH_MAX]; - - canonicalize_int(path, canonic); - - if FUNCTION_SANDBOX_SAFE - ("chown", canonic) { - check_dlsym(chown); - result = true_chown(path, owner, group); - } - - return result; -} - -int -creat(const char *pathname, mode_t mode) -{ -/* Is it a system call? */ - int result = -1; - char canonic[SB_PATH_MAX]; - - canonicalize_int(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE - ("creat", canonic) { - check_dlsym(open); - result = true_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); - } - - return result; -} - -FILE * -fopen(const char *pathname, const char *mode) -{ - FILE *result = NULL; - char canonic[SB_PATH_MAX]; - - canonicalize_ptr(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE_CHAR - ("fopen", canonic, mode) { - check_dlsym(fopen); - result = true_fopen(pathname, mode); - } - - return result; -} - -int -lchown(const char *path, uid_t owner, gid_t group) -{ - int result = -1; - char canonic[SB_PATH_MAX]; - - canonicalize_int(path, canonic); - - if FUNCTION_SANDBOX_SAFE - ("lchown", canonic) { - check_dlsym(lchown); - result = true_lchown(path, owner, group); - } - - return result; -} - -int -link(const char *oldpath, const char *newpath) -{ - int result = -1; - char old_canonic[SB_PATH_MAX], new_canonic[SB_PATH_MAX]; - - canonicalize_int(oldpath, old_canonic); - canonicalize_int(newpath, new_canonic); - - if FUNCTION_SANDBOX_SAFE - ("link", new_canonic) { - check_dlsym(link); - result = true_link(oldpath, newpath); - } - - return result; -} - -int -mkdir(const char *pathname, mode_t mode) -// returns 0 success, or -1 if an error occurred -{ - int result = -1, my_errno = errno; - char canonic[SB_PATH_MAX]; - struct stat st; - - canonicalize_int(pathname, canonic); - - /* Check if the directory exist, return EEXIST rather than failing */ - if (0 == lstat(canonic, &st)) { - errno = EEXIST; - return -1; - } - errno = my_errno; - - if FUNCTION_SANDBOX_SAFE - ("mkdir", canonic) { - check_dlsym(mkdir); - result = true_mkdir(pathname, mode); - } - - return result; -} - -DIR * -opendir(const char *name) -{ - DIR *result = NULL; - char canonic[SB_PATH_MAX]; - - canonicalize_ptr(name, canonic); - - if FUNCTION_SANDBOX_SAFE - ("opendir", canonic) { - check_dlsym(opendir); - result = true_opendir(name); - } - - return result; -} - -#ifdef WRAP_MKNOD - -int -__xmknod(const char *pathname, mode_t mode, dev_t dev) -{ - int result = -1; - char canonic[SB_PATH_MAX]; - - canonicalize_int(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE - ("__xmknod", canonic) { - check_dlsym(__xmknod); - result = true___xmknod(pathname, mode, dev); - } - - return result; -} - -#endif - -int -open(const char *pathname, int flags, ...) -{ -/* Eventually, there is a third parameter: it's mode_t mode */ - va_list ap; - mode_t mode = 0; - int result = -1; - char canonic[SB_PATH_MAX]; - - if (flags & O_CREAT) { - va_start(ap, flags); - mode = va_arg(ap, mode_t); - va_end(ap); - } - - canonicalize_int(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE_INT - ("open", canonic, flags) { - /* We need to resolve open() realtime in some cases, - * else we get a segfault when running /bin/ps, etc - * in a sandbox */ - check_dlsym(open); - result = true_open(pathname, flags, mode); - } - - return result; -} - -int -rename(const char *oldpath, const char *newpath) -{ - int result = -1; - char old_canonic[SB_PATH_MAX], new_canonic[SB_PATH_MAX]; - - canonicalize_int(oldpath, old_canonic); - canonicalize_int(newpath, new_canonic); - - if (FUNCTION_SANDBOX_SAFE("rename", old_canonic) && - FUNCTION_SANDBOX_SAFE("rename", new_canonic)) { - check_dlsym(rename); - result = true_rename(oldpath, newpath); - } - - return result; -} - -int -rmdir(const char *pathname) -{ - int result = -1; - char canonic[SB_PATH_MAX]; - - canonicalize_int(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE - ("rmdir", canonic) { - check_dlsym(rmdir); - result = true_rmdir(pathname); - } - - return result; -} - -int -symlink(const char *oldpath, const char *newpath) -{ - int result = -1; - char old_canonic[SB_PATH_MAX], new_canonic[SB_PATH_MAX]; - - canonicalize_int(oldpath, old_canonic); - canonicalize_int(newpath, new_canonic); - - if FUNCTION_SANDBOX_SAFE - ("symlink", new_canonic) { - check_dlsym(symlink); - result = true_symlink(oldpath, newpath); - } - - return result; -} - -int -truncate(const char *path, TRUNCATE_T length) -{ - int result = -1; - char canonic[SB_PATH_MAX]; - - canonicalize_int(path, canonic); - - if FUNCTION_SANDBOX_SAFE - ("truncate", canonic) { - check_dlsym(truncate); - result = true_truncate(path, length); - } - - return result; -} - -int -unlink(const char *pathname) -{ - int result = -1; - char canonic[SB_PATH_MAX]; - - canonicalize_int(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE - ("unlink", canonic) { - check_dlsym(unlink); - result = true_unlink(pathname); - } - - return result; -} - -#if (GLIBC_MINOR >= 1) - -int -creat64(const char *pathname, __mode_t mode) -{ -/* Is it a system call? */ - int result = -1; - char canonic[SB_PATH_MAX]; - - canonicalize_int(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE - ("creat64", canonic) { - check_dlsym(open64); - result = true_open64(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); - } - - return result; -} - -FILE * -fopen64(const char *pathname, const char *mode) -{ - FILE *result = NULL; - char canonic[SB_PATH_MAX]; - - canonicalize_ptr(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE_CHAR - ("fopen64", canonic, mode) { - check_dlsym(fopen64); - result = true_fopen(pathname, mode); - } - - return result; -} - -int -open64(const char *pathname, int flags, ...) -{ -/* Eventually, there is a third parameter: it's mode_t mode */ - va_list ap; - mode_t mode = 0; - int result = -1; - char canonic[SB_PATH_MAX]; - - if (flags & O_CREAT) { - va_start(ap, flags); - mode = va_arg(ap, mode_t); - va_end(ap); - } - - canonicalize_int(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE_INT - ("open64", canonic, flags) { - check_dlsym(open64); - result = true_open64(pathname, flags, mode); - } - - return result; -} - -int -truncate64(const char *path, __off64_t length) -{ - int result = -1; - char canonic[SB_PATH_MAX]; - - canonicalize_int(path, canonic); - - if FUNCTION_SANDBOX_SAFE - ("truncate64", canonic) { - check_dlsym(truncate64); - result = true_truncate64(path, length); - } - - return result; -} - -#endif /* GLIBC_MINOR >= 1 */ - -/* - * Exec Wrappers - */ - -int -execve(const char *filename, char *const argv[], char *const envp[]) -{ - int old_errno = errno; - int result = -1; - int count = 0; - int env_len = 0; - char canonic[SB_PATH_MAX]; - char **my_env = NULL; - int kill_env = 1; - /* We limit the size LD_PRELOAD can be here, but it should be enough */ - char tmp_str[4096]; - - canonicalize_int(filename, canonic); - - if FUNCTION_SANDBOX_SAFE - ("execve", canonic) { - while (envp[count] != NULL) { - if (strstr(envp[count], "LD_PRELOAD=") == envp[count]) { - if (NULL != strstr(envp[count], sandbox_lib)) { - my_env = (char **) envp; - kill_env = 0; - break; - } else { - int i = 0; - const int max_envp_len = - strlen(envp[count]) + strlen(sandbox_lib) + 1; - - /* Fail safe ... */ - if (max_envp_len > 4096) { - fprintf(stderr, "sandbox: max_envp_len too big!\n"); - errno = ENOMEM; - return result; - } - - /* Calculate envp size */ - my_env = (char **) envp; - do - env_len += 1; - while (*my_env++); - - my_env = (char **) malloc((env_len + 2) * sizeof (char *)); - if (NULL == my_env) { - errno = ENOMEM; - return result; - } - /* Copy envp to my_env */ - do - my_env[i] = envp[i]; - while (envp[i++]); - - /* Set tmp_str to envp[count] */ - strncpy(tmp_str, envp[count], max_envp_len - 1); - - /* LD_PRELOAD already have variables other than sandbox_lib, - * thus we have to add sandbox_lib seperated via a whitespace. */ - if (0 != strncmp(envp[count], "LD_PRELOAD=", max_envp_len - 1)) { - strncat(tmp_str, " ", max_envp_len - strlen(tmp_str)); - strncat(tmp_str, sandbox_lib, max_envp_len - strlen(tmp_str)); - } else { - strncat(tmp_str, sandbox_lib, max_envp_len - strlen(tmp_str)); - } - - /* Valid string? */ - tmp_str[max_envp_len] = '\0'; - - /* Ok, replace my_env[count] with our version that contains - * sandbox_lib ... */ - my_env[count] = tmp_str; - - break; - } - } - count++; - } - - errno = old_errno; - check_dlsym(execve); - result = true_execve(filename, argv, my_env); - old_errno = errno; - - if (my_env && kill_env) { - free(my_env); - my_env = NULL; - } - } - - errno = old_errno; - - return result; -} - -/* - * Internal Functions - */ - -#if (GLIBC_MINOR == 1) - -/* This hack is needed for glibc 2.1.1 (and others?) - * (not really needed, but good example) */ -extern int fclose(FILE *); -static int (*true_fclose) (FILE *) = NULL; -int -fclose(FILE * file) -{ - int result = -1; - - check_dlsym(fclose); - result = true_fclose(file); - - return result; -} - -#endif /* GLIBC_MINOR == 1 */ - -static void -init_context(sbcontext_t * context) -{ - context->show_access_violation = 1; - context->deny_prefixes = NULL; - context->num_deny_prefixes = 0; - context->read_prefixes = NULL; - context->num_read_prefixes = 0; - context->write_prefixes = NULL; - context->num_write_prefixes = 0; - context->predict_prefixes = NULL; - context->num_predict_prefixes = 0; - context->write_denied_prefixes = NULL; - context->num_write_denied_prefixes = 0; -} - -static int -is_sandbox_pid() -{ - int old_errno = errno; - int result = 0; - FILE *pids_stream = NULL; - int pids_file = -1; - int current_pid = 0; - int tmp_pid = 0; - - init_wrappers(); - - pids_stream = true_fopen(sandbox_pids_file, "r"); - - if (NULL == pids_stream) { - perror(">>> pids file fopen"); - } else { - pids_file = fileno(pids_stream); - - if (pids_file < 0) { - perror(">>> pids file fileno"); - } else { - current_pid = getpid(); - - while (EOF != fscanf(pids_stream, "%d\n", &tmp_pid)) { - if (tmp_pid == current_pid) { - result = 1; - break; - } - } - } - if (EOF == fclose(pids_stream)) { - perror(">>> pids file fclose"); - } - pids_stream = NULL; - pids_file = -1; - } - - errno = old_errno; - - return result; -} - -static void -clean_env_entries(char ***prefixes_array, int *prefixes_num) -{ - int old_errno = errno; - int i = 0; - - if (NULL != *prefixes_array) { - for (i = 0; i < *prefixes_num; i++) { - if (NULL != (*prefixes_array)[i]) { - free((*prefixes_array)[i]); - (*prefixes_array)[i] = NULL; - } - } - if (*prefixes_array) - free(*prefixes_array); - *prefixes_array = NULL; - *prefixes_num = 0; - } - - errno = old_errno; -} - -static void -init_env_entries(char ***prefixes_array, int *prefixes_num, char *env, int warn) -{ - int old_errno = errno; - char *prefixes_env = getenv(env); - - if (NULL == prefixes_env) { - fprintf(stderr, - "Sandbox error : the %s environmental variable should be defined.\n", - env); - } else { - char *buffer = NULL; - int prefixes_env_length = strlen(prefixes_env); - int i = 0; - int num_delimiters = 0; - char *token = NULL; - char *prefix = NULL; - - for (i = 0; i < prefixes_env_length; i++) { - if (':' == prefixes_env[i]) { - num_delimiters++; - } - } - - if (num_delimiters > 0) { - *prefixes_array = - (char **) malloc((num_delimiters + 1) * sizeof (char *)); - buffer = strndupa(prefixes_env, prefixes_env_length); - -#ifdef REENTRANT_STRTOK - token = strtok_r(buffer, ":", &buffer); -#else - token = strtok(buffer, ":"); -#endif - - while ((NULL != token) && (strlen(token) > 0)) { - prefix = strndup(token, strlen(token)); - (*prefixes_array)[(*prefixes_num)++] = filter_path(prefix); - -#ifdef REENTRANT_STRTOK - token = strtok_r(NULL, ":", &buffer); -#else - token = strtok(NULL, ":"); -#endif - - if (prefix) - free(prefix); - prefix = NULL; - } - } else if (prefixes_env_length > 0) { - (*prefixes_array) = (char **) malloc(sizeof (char *)); - - (*prefixes_array)[(*prefixes_num)++] = filter_path(prefixes_env); - } - } - - errno = old_errno; -} - -static char * -filter_path(const char *path) -{ - int old_errno = errno; - char *filtered_path = (char *) malloc(SB_PATH_MAX * sizeof (char)); - - canonicalize_ptr(path, filtered_path); - - errno = old_errno; - - return filtered_path; -} - -static int -check_access(sbcontext_t * sbcontext, const char *func, const char *path) -{ - int old_errno = errno; - int result = -1; - int i = 0; - char *filtered_path = filter_path(path); - - if ('/' != filtered_path[0]) { - errno = old_errno; - - if (filtered_path) - free(filtered_path); - filtered_path = NULL; - - return 0; - } - - if ((0 == strncmp(filtered_path, "/etc/ld.so.preload", 18)) - && (is_sandbox_pid())) { - result = 1; - } - - if (-1 == result) { - if (NULL != sbcontext->deny_prefixes) { - for (i = 0; i < sbcontext->num_deny_prefixes; i++) { - if (NULL != sbcontext->deny_prefixes[i]) { - if (0 == strncmp(filtered_path, - sbcontext-> - deny_prefixes[i], - strlen(sbcontext->deny_prefixes[i]))) { - result = 0; - break; - } - } - } - } - - if (-1 == result) { - if ((NULL != sbcontext->read_prefixes) && - ((0 == strncmp(func, "open_rd", 7)) || - (0 == strncmp(func, "popen", 5)) || - (0 == strncmp(func, "opendir", 7)) || - (0 == strncmp(func, "system", 6)) || - (0 == strncmp(func, "execl", 5)) || - (0 == strncmp(func, "execlp", 6)) || - (0 == strncmp(func, "execle", 6)) || - (0 == strncmp(func, "execv", 5)) || - (0 == strncmp(func, "execvp", 6)) || - (0 == strncmp(func, "execve", 6)) - ) - ) { - for (i = 0; i < sbcontext->num_read_prefixes; i++) { - if (NULL != sbcontext->read_prefixes[i]) { - if (0 == strncmp(filtered_path, - sbcontext-> - read_prefixes[i], - strlen(sbcontext->read_prefixes[i]))) { - result = 1; - break; - } - } - } - } else if ((NULL != sbcontext->write_prefixes) && - ((0 == strncmp(func, "open_wr", 7)) || - (0 == strncmp(func, "creat", 5)) || - (0 == strncmp(func, "creat64", 7)) || - (0 == strncmp(func, "mkdir", 5)) || - (0 == strncmp(func, "mknod", 5)) || - (0 == strncmp(func, "mkfifo", 6)) || - (0 == strncmp(func, "link", 4)) || - (0 == strncmp(func, "symlink", 7)) || - (0 == strncmp(func, "rename", 6)) || - (0 == strncmp(func, "utime", 5)) || - (0 == strncmp(func, "utimes", 6)) || - (0 == strncmp(func, "unlink", 6)) || - (0 == strncmp(func, "rmdir", 5)) || - (0 == strncmp(func, "chown", 5)) || - (0 == strncmp(func, "lchown", 6)) || - (0 == strncmp(func, "chmod", 5)) || - (0 == strncmp(func, "truncate", 8)) || - (0 == strncmp(func, "ftruncate", 9)) || - (0 == strncmp(func, "truncate64", 10)) || - (0 == strncmp(func, "ftruncate64", 11)) - ) - ) { - struct stat tmp_stat; - - for (i = 0; i < sbcontext->num_write_denied_prefixes; i++) { - if (NULL != sbcontext->write_denied_prefixes[i]) { - if (0 == - strncmp(filtered_path, - sbcontext-> - write_denied_prefixes - [i], strlen(sbcontext->write_denied_prefixes[i]))) { - result = 0; - break; - } - } - } - - if (-1 == result) { - for (i = 0; i < sbcontext->num_write_prefixes; i++) { - if (NULL != sbcontext->write_prefixes[i]) { - if (0 == - strncmp - (filtered_path, - sbcontext->write_prefixes[i], - strlen(sbcontext->write_prefixes[i]))) { - result = 1; - break; - } - } - } - - if (-1 == result) { - /* hack to prevent mkdir of existing dirs to show errors */ - if (0 == strncmp(func, "mkdir", 5)) { - if (0 == stat(filtered_path, &tmp_stat)) { - sbcontext->show_access_violation = 0; - result = 0; - } - } - - if (-1 == result) { - for (i = 0; i < sbcontext->num_predict_prefixes; i++) { - if (NULL != sbcontext->predict_prefixes[i]) { - if (0 == - strncmp - (filtered_path, - sbcontext-> - predict_prefixes[i], - strlen(sbcontext->predict_prefixes[i]))) { - sbcontext->show_access_violation = 0; - result = 0; - break; - } - } - } - } - } - } - } - } - } - - if (-1 == result) { - result = 0; - } - - if (filtered_path) - free(filtered_path); - filtered_path = NULL; - - errno = old_errno; - - return result; -} - -static int -check_syscall(sbcontext_t * sbcontext, const char *func, const char *file) -{ - int old_errno = errno; - int result = 1; - struct stat log_stat; - char *log_path = NULL; - char *absolute_path = NULL; - char *tmp_buffer = NULL; - int log_file = 0; - struct stat debug_log_stat; - char *debug_log_env = NULL; - char *debug_log_path = NULL; - int debug_log_file = 0; - char buffer[512]; - char *dpath = NULL; - - init_wrappers(); - - if ('/' == file[0]) { - absolute_path = (char *) malloc((strlen(file) + 1) * sizeof (char)); - sprintf(absolute_path, "%s", file); - } else { - tmp_buffer = (char *) malloc(SB_PATH_MAX * sizeof (char)); - egetcwd(tmp_buffer, SB_PATH_MAX - 1); - absolute_path = (char *) malloc((strlen(tmp_buffer) + 1 + strlen(file) + 1) * sizeof (char)); - sprintf(absolute_path, "%s/%s", tmp_buffer, file); - if (tmp_buffer) - free(tmp_buffer); - tmp_buffer = NULL; - } - - log_path = getenv("SANDBOX_LOG"); - debug_log_env = getenv("SANDBOX_DEBUG"); - debug_log_path = getenv("SANDBOX_DEBUG_LOG"); - - if (((NULL == log_path) || - (0 != strncmp(absolute_path, log_path, strlen(log_path)))) && - ((NULL == debug_log_env) || - (NULL == debug_log_path) || - (0 != strncmp(absolute_path, debug_log_path, strlen(debug_log_path)))) - && (0 == check_access(sbcontext, func, absolute_path)) - ) { - if (1 == sbcontext->show_access_violation) { - fprintf(stderr, - "\e[31;01mACCESS DENIED\033[0m %s:%*s%s\n", - func, (int) (10 - strlen(func)), "", absolute_path); - - if (NULL != log_path) { - sprintf(buffer, "%s:%*s%s\n", func, (int) (10 - strlen(func)), "", - absolute_path); - // log_path somehow gets corrupted. figuring out why would be good. - dpath = strdup(log_path); - if ((0 == lstat(log_path, &log_stat)) - && (0 == S_ISREG(log_stat.st_mode)) - ) { - fprintf(stderr, - "\e[31;01mSECURITY BREACH\033[0m %s already exists and is not a regular file.\n", - dpath); - } else if (0 == check_access(sbcontext, "open_wr", dpath)) { - unsetenv("SANDBOX_LOG"); - fprintf(stderr, - "\e[31;01mSECURITY BREACH\033[0m SANDBOX_LOG %s isn't allowed via SANDBOX_WRITE\n", - dpath); - } else { - log_file = true_open(dpath, - O_APPEND | O_WRONLY - | O_CREAT, - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (log_file >= 0) { - write(log_file, buffer, strlen(buffer)); - close(log_file); - } - } - free(dpath); - } - } - - result = 0; - } else if (NULL != debug_log_env) { - if (NULL != debug_log_path) { - if (0 != strncmp(absolute_path, debug_log_path, strlen(debug_log_path))) { - sprintf(buffer, "%s:%*s%s\n", func, (int) (10 - strlen(func)), "", - absolute_path); - //debug_log_path somehow gets corupted, same thing as log_path above. - dpath = strdup(debug_log_path); - if ((0 == lstat(debug_log_path, &debug_log_stat)) - && (0 == S_ISREG(debug_log_stat.st_mode)) - ) { - fprintf(stderr, - "\e[31;01mSECURITY BREACH\033[0m %s already exists and is not a regular file.\n", - debug_log_path); - } else if (0 == check_access(sbcontext, "open_wr", dpath)) { - unsetenv("SANDBOX_DEBUG"); - unsetenv("SANDBOX_DEBUG_LOG"); - fprintf(stderr, - "\e[31;01mSECURITY BREACH\033[0m SANDBOX_DEBUG_LOG %s isn't allowed by SANDBOX_WRITE.\n", - dpath); - } else { - debug_log_file = - true_open(dpath, - O_APPEND | O_WRONLY | - O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (debug_log_file >= 0) { - write(debug_log_file, buffer, strlen(buffer)); - close(debug_log_file); - } - } - free(dpath); - } - } else { - fprintf(stderr, - "\e[32;01mACCESS ALLOWED\033[0m %s:%*s%s\n", - func, (int) (10 - strlen(func)), "", absolute_path); - } - } - - if (absolute_path) - free(absolute_path); - absolute_path = NULL; - - errno = old_errno; - - return result; -} - -static int -is_sandbox_on() -{ - int old_errno = errno; - - /* $SANDBOX_ACTIVE is an env variable that should ONLY - * be used internal by sandbox.c and libsanbox.c. External - * sources should NEVER set it, else the sandbox is enabled - * in some cases when run in parallel with another sandbox, - * but not even in the sandbox shell. - * - * Azarah (3 Aug 2002) - */ - if ((NULL != getenv("SANDBOX_ON")) && - (0 == strncmp(getenv("SANDBOX_ON"), "1", 1)) && - (NULL != getenv("SANDBOX_ACTIVE")) && - (0 == strncmp(getenv("SANDBOX_ACTIVE"), "armedandready", 13)) - ) { - errno = old_errno; - - return 1; - } else { - errno = old_errno; - - return 0; - } -} - -static int -before_syscall(const char *func, const char *file) -{ - int old_errno = errno; - int result = 1; - sbcontext_t sbcontext; - - if (!strlen(file)) { - /* The file/directory does not exist */ - errno = ENOENT; - return 0; - } - - init_context(&sbcontext); - - init_env_entries(&(sbcontext.deny_prefixes), - &(sbcontext.num_deny_prefixes), "SANDBOX_DENY", 1); - init_env_entries(&(sbcontext.read_prefixes), - &(sbcontext.num_read_prefixes), "SANDBOX_READ", 1); - init_env_entries(&(sbcontext.write_prefixes), - &(sbcontext.num_write_prefixes), "SANDBOX_WRITE", 1); - init_env_entries(&(sbcontext.predict_prefixes), - &(sbcontext.num_predict_prefixes), "SANDBOX_PREDICT", 1); - - result = check_syscall(&sbcontext, func, file); - - clean_env_entries(&(sbcontext.deny_prefixes), &(sbcontext.num_deny_prefixes)); - clean_env_entries(&(sbcontext.read_prefixes), &(sbcontext.num_read_prefixes)); - clean_env_entries(&(sbcontext.write_prefixes), - &(sbcontext.num_write_prefixes)); - clean_env_entries(&(sbcontext.predict_prefixes), - &(sbcontext.num_predict_prefixes)); - - errno = old_errno; - - if (0 == result) { - errno = EACCES; - } - - return result; -} - -static int -before_syscall_open_int(const char *func, const char *file, int flags) -{ - if ((flags & O_WRONLY) || (flags & O_RDWR)) { - return before_syscall("open_wr", file); - } else { - return before_syscall("open_rd", file); - } -} - -static int -before_syscall_open_char(const char *func, const char *file, const char *mode) -{ - if (*mode == 'r' && ((strcmp(mode, "r") == 0) || - /* The strspn accept args are known non-writable modifiers */ - (strlen(++mode) == strspn(mode, "xbtmc")))) { - return before_syscall("open_rd", file); - } else { - return before_syscall("open_wr", file); - } -} - -#include "getcwd.c" -#include "canonicalize.c" - -// vim:expandtab noai:cindent ai diff --git a/src/sandbox-1.1/sandbox.bashrc b/src/sandbox-1.1/sandbox.bashrc deleted file mode 100644 index 5b2a8d752..000000000 --- a/src/sandbox-1.1/sandbox.bashrc +++ /dev/null @@ -1,8 +0,0 @@ -# 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> -# $Id: /var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/sandbox.bashrc,v 1.2.4.1 2004/10/22 16:53:30 carpaski Exp $ -source /etc/profile -export LD_PRELOAD="$SANDBOX_LIB" -alias make="make LD_PRELOAD=$SANDBOX_LIB" -alias su="su -c '/bin/bash -rcfile $SANDBOX_DIR/sandbox.bashrc'" diff --git a/src/sandbox-1.1/sandbox.c b/src/sandbox-1.1/sandbox.c deleted file mode 100644 index a33f03717..000000000 --- a/src/sandbox-1.1/sandbox.c +++ /dev/null @@ -1,863 +0,0 @@ -/* -** Path sandbox for the gentoo linux portage package system, initially -** based on the ROCK Linux Wrapper for getting a list of created files -** -** to integrate with bash, bash should have been built like this -** -** ./configure --prefix=<prefix> --host=<host> --without-gnu-malloc -** -** it's very important that the --enable-static-link option is NOT specified -** -** 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> -** $Id: /var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/sandbox.c,v 1.20.2.1 2004/12/01 22:14:09 carpaski Exp $ -*/ - -/* #define _GNU_SOURCE */ - -#include <errno.h> -#include <fcntl.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> -#include <string.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/resource.h> -#include <sys/wait.h> -#include <unistd.h> -#include <fcntl.h> -#include "sandbox.h" - -int preload_adaptable = 1; -int cleaned_up = 0; -int print_debug = 0; -int stop_called = 0; - -/* Read pids file, and load active pids into an array. Return number of pids in array */ -int -load_active_pids(int fd, int **pids) -{ - char *data = NULL; - char *ptr = NULL, *ptr2 = NULL; - int my_pid; - int num_pids = 0; - long len; - - pids[0] = NULL; - - len = file_length(fd); - - /* Allocate and zero datablock to read pids file */ - data = (char *) malloc((len + 1) * sizeof (char)); - memset(data, 0, len + 1); - - /* Start at beginning of file */ - lseek(fd, 0L, SEEK_SET); - - /* read entire file into a buffer */ - read(fd, data, len); - - ptr = data; - - /* Loop and read all pids */ - while (1) { - /* Find new line */ - ptr2 = strchr(ptr, '\n'); - if (ptr2 == NULL) - break; /* No more PIDs */ - - /* Clear the \n. And ptr should have a null-terminated decimal string */ - ptr2[0] = 0; - - my_pid = atoi(ptr); - - /* If the PID is still alive, add it to our array */ - if ((0 != my_pid) && (0 == kill(my_pid, 0))) { - pids[0] = (int *) realloc(pids[0], (num_pids + 1) * sizeof (int)); - pids[0][num_pids] = my_pid; - num_pids++; - } - - /* Put ptr past the NULL we just wrote */ - ptr = ptr2 + 1; - } - - if (data) - free(data); - data = NULL; - - return num_pids; -} - -/* Read ld.so.preload file, and loads dirs into an array. Return number of entries in array */ -int -load_preload_libs(int fd, char ***preloads) -{ - char *data = NULL; - char *ptr = NULL, *ptr2 = NULL; - int num_entries = 0; - long len; - - preloads[0] = NULL; - - len = file_length(fd); - - /* Allocate and zero datablock to read pids file */ - data = (char *) malloc((len + 1) * sizeof (char)); - memset(data, 0, len + 1); - - /* Start at beginning of file */ - lseek(fd, 0L, SEEK_SET); - - /* read entire file into a buffer */ - read(fd, data, len); - - ptr = data; - - /* Loop and read all pids */ - while (1) { - /* Find new line */ - ptr2 = strchr(ptr, '\n'); - - /* Clear the \n. And ptr should have a null-terminated decimal string - * Don't break from the loop though because the last line may not - * terminated with a \n - */ - if (NULL != ptr2) - ptr2[0] = 0; - - /* If listing does not match our libname, add it to the array */ - if ((strlen(ptr)) && (NULL == strstr(ptr, LIB_NAME))) { - preloads[0] = - (char **) realloc(preloads[0], (num_entries + 1) * sizeof (char **)); - preloads[0][num_entries] = strdup(ptr); - num_entries++; - } - - if (NULL == ptr2) - break; /* No more PIDs */ - - /* Put ptr past the NULL we just wrote */ - ptr = ptr2 + 1; - } - - if (data) - free(data); - data = NULL; - - return num_entries; -} - -void -cleanup() -{ - int i = 0; - int success = 1; - int pids_file = -1, num_of_pids = 0; - int *pids_array = NULL; - char pid_string[255]; - char *sandbox_pids_file; -#ifdef USE_LD_SO_PRELOAD - int preload_file = -1, num_of_preloads = 0; - char preload_entry[255]; - char **preload_array = NULL; -#endif - - /* Generate sandbox pids-file path */ - sandbox_pids_file = get_sandbox_pids_file(); - - /* Remove this sandbox's bash pid from the global pids - * file if it has rights to adapt the ld.so.preload file */ - if ((1 == preload_adaptable) && (0 == cleaned_up)) { - cleaned_up = 1; - success = 1; - - if (print_debug) - printf("Cleaning up pids file.\n"); - - /* Stat the PIDs file, make sure it exists and is a regular file */ - if (file_exist(sandbox_pids_file, 1) <= 0) { - 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 */ - return; - } - - pids_file = file_open(sandbox_pids_file, "r+", 1, 0664, "portage"); - if (-1 == pids_file) { - success = 0; - /* Nothing more to do here */ - return; - } - - /* Load "still active" pids into an array */ - num_of_pids = load_active_pids(pids_file, &pids_array); - //printf("pids: %d\r\n", num_of_pids); - -#ifdef USE_LD_SO_PRELOAD - /* clean the /etc/ld.so.preload file if no other sandbox - * processes are running anymore */ - if (1 == num_of_pids) { - success = 1; - - if (print_debug) - printf("Cleaning up /etc/ld.so.preload.\n"); - - preload_file = file_open("/etc/ld.so.preload", "r+", 1, 0644); - if (-1 != preload_file) { - /* Load all the preload libraries into an array */ - num_of_preloads = load_preload_libs(preload_file, &preload_array); - //printf("num preloads: %d\r\n", num_of_preloads); - /* Clear file */ - file_truncate(preload_file); - - /* store the other preload libraries back into the /etc/ld.so.preload file */ - if (num_of_preloads > 0) { - for (i = 0; i < num_of_preloads; i++) { - sprintf(preload_entry, "%s\n", preload_array[i]); - if (write - (preload_file, - preload_entry, - strlen(preload_entry)) != strlen(preload_entry)) { - perror(">>> /etc/ld.so.preload file write"); - success = 0; - break; - } - } - } - - /* Free memory used to store preload array */ - for (i = 0; i < num_of_preloads; i++) { - if (preload_array[i]) - free(preload_array[i]); - preload_array[i] = NULL; - } - if (preload_array) - free(preload_array); - preload_array = NULL; - - file_close(preload_file); - preload_file = -1; - } - } -#endif - - file_truncate(pids_file); - - /* if pids are still running, write only the running pids back to the file */ - if (num_of_pids > 1) { - for (i = 0; i < num_of_pids; i++) { - if (pids_array[i] != getpid()) { - sprintf(pid_string, "%d\n", pids_array[i]); - - if (write(pids_file, pid_string, strlen(pid_string)) != - strlen(pid_string)) { - perror(">>> pids file write"); - success = 0; - break; - } - } - } - - file_close(pids_file); - pids_file = -1; - } else { - - file_close(pids_file); - pids_file = -1; - - /* remove the pidsfile, as this was the last sandbox */ - unlink(sandbox_pids_file); - } - - if (pids_array != NULL) - free(pids_array); - pids_array = NULL; - } - - free(sandbox_pids_file); - if (0 == success) - return; -} - -void -stop(int signum) -{ - if (stop_called == 0) { - stop_called = 1; - printf("Caught signal %d in pid %d\r\n", signum, getpid()); - cleanup(); - } else { - fprintf(stderr, "Pid %d alreadly caught signal and is still cleaning up\n", getpid()); - } -} - -void -setenv_sandbox_write(char *home_dir, char *portage_tmp_dir, char *var_tmp_dir, - char *tmp_dir) -{ - char buf[1024]; - - /* bzero out entire buffer then append trailing 0 */ - memset(buf, 0, sizeof(buf)); - - if (!getenv(ENV_SANDBOX_WRITE)) { - /* these could go into make.globals later on */ - snprintf(buf, sizeof(buf), - "%s:%s/.gconfd/lock:%s/.bash_history:", \ - "/dev/zero:/dev/fd/:/dev/null:/dev/pts/:" \ - "/dev/vc/:/dev/tty:/tmp/:" \ - "/dev/shm/ngpt:/var/log/scrollkeeper.log:" \ - "/usr/tmp/conftest:/usr/lib/conftest:" \ - "/usr/lib32/conftest:/usr/lib64/conftest:" \ - "/usr/tmp/cf:/usr/lib/cf:/usr/lib32/cf:/usr/lib64/cf", - home_dir, home_dir); - - if (NULL == portage_tmp_dir) { - strncat(buf, tmp_dir, sizeof(buf)); - strncat(buf, ":", sizeof(buf)); - strncat(buf, var_tmp_dir, sizeof(buf)); - strncat(buf, ":/tmp/:/var/tmp/", sizeof(buf)); - } else { - strncat(buf, portage_tmp_dir, sizeof(buf)); - strncat(buf, ":", sizeof(buf)); - strncat(buf, tmp_dir, sizeof(buf)); - strncat(buf, ":", sizeof(buf)); - strncat(buf, var_tmp_dir, sizeof(buf)); - strncat(buf, ":/tmp/:/var/tmp/", sizeof(buf)); - } - buf[sizeof(buf) - 1] = '\0'; - setenv(ENV_SANDBOX_WRITE, buf, 1); - } -} - -void -setenv_sandbox_predict(char *home_dir) -{ - char buf[1024]; - - memset(buf, 0, sizeof(buf)); - - if (!getenv(ENV_SANDBOX_PREDICT)) { - /* these should go into make.globals later on */ - snprintf(buf, sizeof(buf), "%s/.:" \ - "/usr/lib/python2.0/:" \ - "/usr/lib/python2.1/:" \ - "/usr/lib/python2.2/:" \ - "/usr/lib/python2.3/:" \ - "/usr/lib/python2.4/:" \ - "/usr/lib/python2.5/:" \ - "/usr/lib/python3.0/:", - home_dir); - - buf[sizeof(buf) - 1] = '\0'; - setenv(ENV_SANDBOX_PREDICT, buf, 1); - } -} - -int -print_sandbox_log(char *sandbox_log) -{ - int sandbox_log_file = -1; - char *beep_count_env = NULL; - int i, color, beep_count = 0; - long len = 0; - char *buffer = NULL; - - sandbox_log_file = file_open(sandbox_log, "r", 1, 0664, "portage"); - if (-1 == sandbox_log_file) - return 0; - - len = file_length(sandbox_log_file); - buffer = (char *) malloc((len + 1) * sizeof (char)); - memset(buffer, 0, len + 1); - read(sandbox_log_file, buffer, len); - file_close(sandbox_log_file); - - color = ( (getenv("NOCOLOR") != NULL) ? 0 : 1); - - if (color) printf("\e[31;01m"); - printf("--------------------------- ACCESS VIOLATION SUMMARY ---------------------------"); - if (color) printf("\033[0m"); - if (color) printf("\e[31;01m"); - printf("\nLOG FILE = \"%s\"", sandbox_log); - if (color) printf("\033[0m"); - printf("\n\n"); - printf("%s", buffer); - if (buffer) - free(buffer); - buffer = NULL; - printf - ("\e[31;01m--------------------------------------------------------------------------------\033[0m\n"); - - beep_count_env = getenv(ENV_SANDBOX_BEEP); - if (beep_count_env) - beep_count = atoi(beep_count_env); - else - beep_count = DEFAULT_BEEP_COUNT; - - for (i = 0; i < beep_count; i++) { - fputc('\a', stderr); - if (i < beep_count - 1) - sleep(1); - } - return 1; -} - -int -spawn_shell(char *argv_bash[]) -{ -#ifdef USE_SYSTEM_SHELL - int i = 0; - char *sh = NULL; - int first = 1; - int ret; - long len = 0; - - while (1) { - if (NULL == argv_bash[i]) - break; - if (NULL != sh) - len = strlen(sh); - sh = (char *) realloc(sh, len + strlen(argv_bash[i]) + 5); - if (first) { - sh[0] = 0; - first = 0; - } - strcat(sh, "\""); - strcat(sh, argv_bash[i]); - strcat(sh, "\" "); - - //printf("%s\n", argv_bash[i]); - i++; - } - printf("%s\n", sh); - ret = system(sh); - if (sh) - free(sh); - sh = NULL; - - if (-1 == ret) - return 0; - return 1; - -#else -# ifndef NO_FORK - int pid; - int status = 0; - int ret = 0; - - pid = fork(); - - /* Child's process */ - if (0 == pid) { -# endif - execv(argv_bash[0], argv_bash); -# ifndef NO_FORK - return 0; - } else if (pid < 0) { - return 0; - } - ret = waitpid(pid, &status, 0); - if ((-1 == ret) || (status > 0)) - return 0; -# endif - return 1; -#endif -} - -int -main(int argc, char **argv) -{ - int i = 0, success = 1; -#ifdef USE_LD_SO_PRELOAD - int preload_file = -1; -#endif - int sandbox_log_presence = 0; - int sandbox_log_file = -1; - int pids_file = -1; - long len; - - int *pids_array = NULL; - int num_of_pids = 0; - - // char run_arg[255]; - char portage_tmp_dir[PATH_MAX]; - char var_tmp_dir[PATH_MAX]; - char tmp_dir[PATH_MAX]; - char sandbox_log[255]; - char sandbox_debug_log[255]; - char sandbox_dir[255]; - char sandbox_lib[255]; - char *sandbox_pids_file; - char sandbox_rc[255]; - char pid_string[255]; - char **argv_bash = NULL; - - char *run_str = "-c"; - char *home_dir = NULL; - char *tmp_string = NULL; -#ifdef USE_LD_SO_PRELOAD - char **preload_array = NULL; - int num_of_preloads = 0; -#endif - - /* Only print info if called with no arguments .... */ - if (argc < 2) - print_debug = 1; - - if (print_debug) - printf - ("========================== Gentoo linux path sandbox ===========================\n"); - - /* check if a sandbox is already running */ - if (NULL != getenv(ENV_SANDBOX_ON)) { - fprintf(stderr, - "Not launching a new sandbox instance\nAnother one is already running in this process hierarchy.\n"); - exit(1); - } else { - - /* determine the location of all the sandbox support files */ - if (print_debug) - printf("Detection of the support files.\n"); - - /* Generate base sandbox path */ - tmp_string = get_sandbox_path(argv[0]); - strncpy(sandbox_dir, tmp_string, 254); - if (tmp_string) - free(tmp_string); - tmp_string = NULL; - strcat(sandbox_dir, "/"); - - /* Generate sandbox lib path */ - tmp_string = get_sandbox_lib(sandbox_dir); - strncpy(sandbox_lib, tmp_string, 254); - if (tmp_string) - free(tmp_string); - tmp_string = NULL; - - /* Generate sandbox pids-file path */ - sandbox_pids_file = get_sandbox_pids_file(); - - /* Generate sandbox bashrc path */ - tmp_string = get_sandbox_rc(sandbox_dir); - strncpy(sandbox_rc, tmp_string, 254); - if (tmp_string) - free(tmp_string); - tmp_string = NULL; - - /* verify the existance of required files */ - if (print_debug) - printf("Verification of the required files.\n"); - -#ifndef SB_HAVE_64BIT_ARCH - if (file_exist(sandbox_lib, 0) <= 0) { - fprintf(stderr, "Could not open the sandbox library at '%s'.\n", - sandbox_lib); - return -1; - } -#endif - if (file_exist(sandbox_rc, 0) <= 0) { - fprintf(stderr, "Could not open the sandbox rc file at '%s'.\n", - sandbox_rc); - return -1; - } -#ifdef USE_LD_SO_PRELOAD - /* ensure that the /etc/ld.so.preload file contains an entry for the sandbox lib */ - if (print_debug) - printf("Setting up the ld.so.preload file.\n"); - - /* check if the /etc/ld.so.preload is a regular file */ - if (file_exist("/etc/ld.so.preload", 1) < 0) { - fprintf(stderr, ">>> /etc/ld.so.preload file is not a regular file\n"); - exit(1); - } - - if (getuid() == 0) { - /* Our r+ also will create the file if it doesn't exist */ - preload_file = file_open("/etc/ld.so.preload", "r+", 1, 0644); - if (-1 == preload_file) { - preload_adaptable = 0; -/* exit(1);*/ - } - } else { - /* Avoid permissions warnings if we're not root */ - preload_adaptable = 0; - } - - /* Only update /etc/ld.so.preload if we can write to it ... */ - if (1 == preload_adaptable) { - /* Load entries of preload table */ - num_of_preloads = load_preload_libs(preload_file, &preload_array); - - /* Zero out our ld.so.preload file */ - file_truncate(preload_file); - - /* Write contents of preload file */ - for (i = 0; i < num_of_preloads + 1; i++) { - /* First entry should be our sandbox library */ - if (0 == i) { - if (write - (preload_file, sandbox_lib, - strlen(sandbox_lib)) != strlen(sandbox_lib)) { - perror(">>> /etc/ld.so.preload file write"); - success = 0; - break; - } - } else { - /* Output all other preload entries */ - if (write - (preload_file, preload_array[i - 1], - strlen(preload_array[i - 1])) != strlen(preload_array[i - 1])) { - perror(">>> /etc/ld.so.preload file write"); - success = 0; - break; - } - } - /* Don't forget the return character after each line! */ - if (1 != write(preload_file, "\n", 1)) { - perror(">>> /etc/ld.so.preload file write"); - success = 0; - break; - } - } - - for (i = 0; i < num_of_preloads; i++) { - if (preload_array[i]) - free(preload_array[i]); - preload_array[i] = NULL; - } - if (preload_array) - free(preload_array); - num_of_preloads = 0; - preload_array = NULL; - } - - /* That's all we needed to do with the preload file */ - if (0 < preload_file) - file_close(preload_file); - preload_file = -1; -#endif - - /* set up the required environment variables */ - if (print_debug) - printf("Setting up the required environment variables.\n"); - - /* Generate sandbox log full path */ - tmp_string = get_sandbox_log(); - strncpy(sandbox_log, tmp_string, 254); - if (tmp_string) - free(tmp_string); - tmp_string = NULL; - - setenv(ENV_SANDBOX_LOG, sandbox_log, 1); - - snprintf(sandbox_debug_log, sizeof(sandbox_debug_log), "%s%s%s", - DEBUG_LOG_FILE_PREFIX, pid_string, LOG_FILE_EXT); - setenv(ENV_SANDBOX_DEBUG_LOG, sandbox_debug_log, 1); - - home_dir = getenv("HOME"); - if (!home_dir) { - home_dir = "/tmp"; - setenv("HOME", home_dir, 1); - } - - /* drobbins: we need to expand these paths using realpath() so that PORTAGE_TMPDIR - * can contain symlinks (example, /var is a symlink, /var/tmp is a symlink.) Without - * this, access is denied to /var/tmp, hurtin' ebuilds. - */ - - { char *e; - e = getenv("PORTAGE_TMPDIR"); - if ( e && ( strlen(e) < sizeof(portage_tmp_dir)-1 ) && (strlen(e) > 1) ) - realpath(e, portage_tmp_dir); - - } - realpath("/var/tmp", var_tmp_dir); - realpath("/tmp", tmp_dir); - - setenv(ENV_SANDBOX_DIR, sandbox_dir, 1); - setenv(ENV_SANDBOX_LIB, sandbox_lib, 1); - setenv("LD_PRELOAD", sandbox_lib, 1); - - if (!getenv(ENV_SANDBOX_DENY)) - setenv(ENV_SANDBOX_DENY, LD_PRELOAD_FILE, 1); - - if (!getenv(ENV_SANDBOX_READ)) - setenv(ENV_SANDBOX_READ, "/", 1); - - /* Set up Sandbox Write path */ - setenv_sandbox_write(home_dir, portage_tmp_dir, var_tmp_dir, tmp_dir); - setenv_sandbox_predict(home_dir); - - setenv(ENV_SANDBOX_ON, "1", 0); - - /* if the portage temp dir was present, cd into it */ - if (NULL != portage_tmp_dir) - chdir(portage_tmp_dir); - - argv_bash = (char **) malloc(6 * sizeof (char *)); - argv_bash[0] = strdup("/bin/bash"); - argv_bash[1] = strdup("-rcfile"); - argv_bash[2] = strdup(sandbox_rc); - - if (argc < 2) - argv_bash[3] = NULL; - else - argv_bash[3] = strdup(run_str); /* "-c" */ - - argv_bash[4] = NULL; /* strdup(run_arg); */ - argv_bash[5] = NULL; - - if (argc >= 2) { - for (i = 1; i < argc; i++) { - if (NULL == argv_bash[4]) - len = 0; - else - len = strlen(argv_bash[4]); - - argv_bash[4] = - (char *) realloc(argv_bash[4], - (len + strlen(argv[i]) + 2) * sizeof (char)); - - if (0 == len) - argv_bash[4][0] = 0; - if (1 != i) - strcat(argv_bash[4], " "); - - strcat(argv_bash[4], argv[i]); - } - } - - /* set up the required signal handlers */ - signal(SIGHUP, &stop); - signal(SIGINT, &stop); - signal(SIGQUIT, &stop); - signal(SIGTERM, &stop); - - /* this one should NEVER be set in ebuilds, as it is the one - * private thing libsandbox.so use to test if the sandbox - * should be active for this pid, or not. - * - * azarah (3 Aug 2002) - */ - - setenv("SANDBOX_ACTIVE", "armedandready", 1); - - /* Load our PID into PIDs file */ - success = 1; - if (file_exist(sandbox_pids_file, 1) < 0) { - success = 0; - 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) - success = 0; - } - if (1 == success) { - /* Grab still active pids */ - num_of_pids = load_active_pids(pids_file, &pids_array); - - /* Zero out file */ - file_truncate(pids_file); - - /* Output active pids, and append our pid */ - for (i = 0; i < num_of_pids + 1; i++) { - /* Time for our entry */ - if (i == num_of_pids) - sprintf(pid_string, "%d\n", getpid()); - else - sprintf(pid_string, "%d\n", pids_array[i]); - - if (write(pids_file, pid_string, strlen(pid_string)) != - strlen(pid_string)) { - perror(">>> pids file write"); - success = 0; - break; - } - } - /* Clean pids_array */ - if (pids_array) - free(pids_array); - pids_array = NULL; - num_of_pids = 0; - - /* We're done with the pids file */ - file_close(pids_file); - } - - /* Something went wrong, bail out */ - if (0 == success) { - perror(">>> pids file write"); - exit(1); - } - - /* STARTING PROTECTED ENVIRONMENT */ - if (print_debug) { - printf("The protected environment has been started.\n"); - printf - ("--------------------------------------------------------------------------------\n"); - } - - if (print_debug) - printf("Shell being started in forked process.\n"); - - /* Start Bash */ - if (!spawn_shell(argv_bash)) { - if (print_debug) - fprintf(stderr, ">>> shell process failed to spawn\n"); - success = 0; - } - - /* Free bash stuff */ - for (i = 0; i < 6; i++) { - if (argv_bash[i]) - free(argv_bash[i]); - argv_bash[i] = NULL; - } - if (argv_bash) - free(argv_bash); - argv_bash = NULL; - - if (print_debug) - printf("Cleaning up sandbox process\n"); - - cleanup(); - - if (print_debug) { - printf - ("========================== Gentoo linux path sandbox ===========================\n"); - printf("The protected environment has been shut down.\n"); - } - - if (file_exist(sandbox_log, 0)) { - sandbox_log_presence = 1; - success = 1; - if (!print_sandbox_log(sandbox_log)) - success = 0; - -#if 0 - if (!success) - exit(1); -#endif - - sandbox_log_file = -1; - } else if (print_debug) { - printf - ("--------------------------------------------------------------------------------\n"); - } - - if ((sandbox_log_presence) || (!success)) - return 1; - else - return 0; - } -} - -// vim:expandtab noai:cindent ai diff --git a/src/sandbox-1.1/sandbox.h b/src/sandbox-1.1/sandbox.h deleted file mode 100644 index 18410affa..000000000 --- a/src/sandbox-1.1/sandbox.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2002 Brad House <brad@mainstreetsoftworks.com>, - * Possibly based on code from Geert Bevin, Uwyn, http://www.uwyn.com - * Distributed under the terms of the GNU General Public License, v2 or later - * Author: Brad House <brad@mainstreetsoftworks.com> - * - * $Id: /var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/sandbox.h,v 1.5.2.1 2004/10/22 16:53:30 carpaski Exp $ - */ - -#ifndef __SANDBOX_H__ -#define __SANDBOX_H__ - -/* Uncomment below to use flock instead of fcntl (POSIX way) to lock/unlock files */ -/* #define USE_FLOCK */ - -/* Uncomment below to use system() to execute the shell rather than execv */ -/* #define USE_SYSTEM_SHELL */ - -/* Uncomment below to use /etc/ld.so.preload (could be very intrusive!!) */ -/* #define USE_LD_SO_PRELOAD */ - -/* Uncommend to not have the protected shell forked, just run in parent process */ -/* ONLY FOR DEBUGGING PURPOSES!! (strace needs it like that) */ -/* #define NO_FORK */ - -#define LD_PRELOAD_FILE "/etc/ld.so.preload" -#define LIB_NAME "libsandbox.so" -#define BASHRC_NAME "sandbox.bashrc" -#define PIDS_FILE "/tmp/sandboxpids.tmp" -#define LOG_FILE_PREFIX "/tmp/sandbox-" -#define DEBUG_LOG_FILE_PREFIX "/tmp/sandbox-debug-" -#define LOG_FILE_EXT ".log" - -#define ENV_SANDBOX_DEBUG_LOG "SANDBOX_DEBUG_LOG" -#define ENV_SANDBOX_LOG "SANDBOX_LOG" -#define ENV_SANDBOX_DIR "SANDBOX_DIR" -#define ENV_SANDBOX_LIB "SANDBOX_LIB" - -#define ENV_SANDBOX_DENY "SANDBOX_DENY" -#define ENV_SANDBOX_READ "SANDBOX_READ" -#define ENV_SANDBOX_WRITE "SANDBOX_WRITE" -#define ENV_SANDBOX_PREDICT "SANDBOX_PREDICT" - -#define ENV_SANDBOX_ON "SANDBOX_ON" -#define ENV_SANDBOX_BEEP "SANDBOX_BEEP" - -#define DEFAULT_BEEP_COUNT 3 - -char *get_sandbox_path(char *argv0); -char *get_sandbox_lib(char *sb_path); -char *get_sandbox_pids_file(void); -char *get_sandbox_rc(char *sb_path); -char *get_sandbox_log(); -char *sb_dirname(const char *path); -int file_getmode(char *mode); -long file_tell(int fp); -int file_lock(int fd, int lock, char *filename); -int file_unlock(int fd); -int file_locktype(char *mode); -int file_open(char *filename, char *mode, int perm_specified, ...); -void file_close(int fd); -long file_length(int fd); -int file_truncate(int fd); -int file_exist(char *filename, int checkmode); - -#endif - -// vim:expandtab noai:cindent ai diff --git a/src/sandbox-1.1/sandbox_futils.c b/src/sandbox-1.1/sandbox_futils.c deleted file mode 100644 index 2f104d936..000000000 --- a/src/sandbox-1.1/sandbox_futils.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * Copyright (C) 2002 Brad House <brad@mainstreetsoftworks.com> - * Distributed under the terms of the GNU General Public License, v2 or later - * Author: Brad House <brad@mainstreetsoftworks.com> - * - * $Id: /var/cvsroot/gentoo-src/portage/src/sandbox-1.1/Attic/sandbox_futils.c,v 1.11.2.1 2004/11/03 13:12:55 ferringb Exp $ - * - */ - -#include <errno.h> -#include <fcntl.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> -#include <string.h> -#include <stdarg.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/resource.h> -#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); - -char * -get_sandbox_path(char *argv0) -{ - char path[255]; - char *cwd = NULL; - - memset(path, 0, sizeof(path)); - /* ARGV[0] specifies full path */ - if (argv0[0] == '/') { - strncpy(path, argv0, sizeof(path)-1); - - /* ARGV[0] specifies relative path */ - } else { - egetcwd(cwd, sizeof(path)-2); - snprintf(path, sizeof(path), "%s/%s", cwd, argv0); - if (cwd) - free(cwd); - cwd = NULL; - } - - /* Return just directory */ - return (sb_dirname(path)); -} - -char * -get_sandbox_lib(char *sb_path) -{ - char path[255]; - -#ifdef SB_HAVE_64BIT_ARCH - snprintf(path, sizeof(path), "%s", LIB_NAME); -#else - snprintf(path, sizeof(path), "/lib/%s", LIB_NAME); - if (file_exist(path, 0) <= 0) { - snprintf(path, sizeof(path), "%s%s", sb_path, LIB_NAME); - } -#endif - return (strdup(path)); -} - -char * -get_sandbox_pids_file(void) -{ - if (0 < getenv("SANDBOX_PIDS_FILE")) { - return (strdup(getenv("SANDBOX_PIDS_FILE"))); - } - return (strdup(PIDS_FILE)); -} - -char * -get_sandbox_rc(char *sb_path) -{ - char path[255]; - - snprintf(path, sizeof(path), "/usr/lib/portage/lib/%s", BASHRC_NAME); - if (file_exist(path, 0) <= 0) { - snprintf(path, sizeof(path), "%s%s", sb_path, BASHRC_NAME); - } - return (strdup(path)); -} - -char * -get_sandbox_log() -{ - char path[255]; - char *sandbox_log_env = NULL; - - /* THIS CHUNK BREAK THINGS BY DOING THIS: - * SANDBOX_LOG=/tmp/sandbox-app-admin/superadduser-1.0.7-11063.log - */ - - sandbox_log_env = getenv(ENV_SANDBOX_LOG); - snprintf(path, sizeof(path)-1, "%s%s%s%d%s", LOG_FILE_PREFIX, - ( sandbox_log_env == NULL ? "" : sandbox_log_env ), - ( sandbox_log_env == NULL ? "" : "-" ), - getpid(), LOG_FILE_EXT); - return (strdup(path)); -} - -/* Obtain base directory name. Do not allow trailing / */ -char * -sb_dirname(const char *path) -{ - char *ret = NULL; - char *ptr = NULL; - int loc = 0, i; - int cut_len = -1; - - /* don't think NULL will ever be passed, but just in case */ - if (NULL == path) - return (strdup(".")); - - /* Grab pointer to last slash */ - ptr = strrchr(path, '/'); - if (NULL == ptr) { - return (strdup(".")); - } - - /* decimal location of pointer */ - loc = ptr - path; - - /* Remove any trailing slash */ - for (i = loc - 1; i >= 0; i--) { - if (path[i] != '/') { - cut_len = i + 1; /* make cut_len the length of the string to keep */ - break; - } - } - - /* It could have been just a plain /, return a 1byte 0 filled string */ - if (-1 == cut_len) - return (strdup("")); - - /* Allocate memory, and return the directory */ - ret = (char *) malloc((cut_len + 1) * sizeof (char)); - memcpy(ret, path, cut_len); - ret[cut_len] = 0; - - return (ret); -} - -/* -char* dirname(const char* path) -{ - char* base = NULL; - unsigned int length = 0; - - base = strrchr(path, '/'); - if (NULL == base) - { - return strdup("."); - } - while (base > path && *base == '/') - { - base--; - } - length = (unsigned int) 1 + base - path; - - base = malloc(sizeof(char)*(length+1)); - memmove(base, path, length); - base[length] = 0; - - return base; -}*/ - -/* Convert text (string) modes to integer values */ -int -file_getmode(char *mode) -{ - int mde = 0; - if (0 == strcasecmp(mode, "r+")) { - mde = O_RDWR | O_CREAT; - } else if (0 == strcasecmp(mode, "w+")) { - mde = O_RDWR | O_CREAT | O_TRUNC; - } else if (0 == strcasecmp(mode, "a+")) { - mde = O_RDWR | O_CREAT | O_APPEND; - } else if (0 == strcasecmp(mode, "r")) { - mde = O_RDONLY; - } else if (0 == strcasecmp(mode, "w")) { - mde = O_WRONLY | O_CREAT | O_TRUNC; - } else if (0 == strcasecmp(mode, "a")) { - mde = O_WRONLY | O_APPEND | O_CREAT; - } else { - mde = O_RDONLY; - } - return (mde); -} - -/* Get current position in file */ -long -file_tell(int fp) -{ - return (lseek(fp, 0L, SEEK_CUR)); -} - -/* lock the file, preferrably the POSIX way */ -int -file_lock(int fd, int lock, char *filename) -{ - int err; -#ifdef USE_FLOCK - if (flock(fd, lock) < 0) { - err = errno; - fprintf(stderr, ">>> %s flock file lock: %s\n", filename, strerror(err)); - return 0; - } -#else - struct flock fl; - fl.l_type = lock; - fl.l_whence = SEEK_SET; - fl.l_start = 0L; - fl.l_len = 0L; - fl.l_pid = getpid(); - if (fcntl(fd, F_SETLKW, &fl) < 0) { - err = errno; - fprintf(stderr, ">>> %s fcntl file lock: %s\n", filename, strerror(err)); - return 0; - } -#endif - return 1; -} - -/* unlock the file, preferrably the POSIX way */ -int -file_unlock(int fd) -{ -#ifdef USE_FLOCK - if (flock(fd, LOCK_UN) < 0) { - perror(">>> flock file unlock"); - return 0; - } -#else - struct flock fl; - fl.l_type = F_UNLCK; - fl.l_whence = SEEK_SET; - fl.l_start = 0L; - fl.l_len = 0L; - fl.l_pid = getpid(); - if (fcntl(fd, F_SETLKW, &fl) < 0) { - perror(">>> fcntl file unlock"); - return 0; - } -#endif - return 1; -} - -/* Auto-determine from how the file was opened, what kind of lock to lock - * the file with - */ -int -file_locktype(char *mode) -{ -#ifdef USE_FLOCK - if (NULL != (strchr(mode, 'w')) || (NULL != strchr(mode, '+')) - || (NULL != strchr(mode, 'a'))) - return (LOCK_EX); - return (LOCK_SH); -#else - if (NULL != (strchr(mode, 'w')) || (NULL != strchr(mode, '+')) - || (NULL != strchr(mode, 'a'))) - return (F_WRLCK); - return (F_RDLCK); -#endif -} - -/* Use standard fopen style modes to open the specified file. Also auto-determines and - * locks the file either in shared or exclusive mode depending on opening mode - */ -int -file_open(char *filename, char *mode, int perm_specified, ...) -{ - int fd; - char error[250]; - va_list ap; - int perm; - char *group = NULL; - struct group *group_struct; - - file_security_check(filename); - - if (perm_specified) { - va_start(ap, perm_specified); - perm = va_arg(ap, int); - group = va_arg(ap, char *); - va_end(ap); - } - fd = open(filename, file_getmode(mode)); - file_security_check(filename); - if (-1 == fd) { - snprintf(error, sizeof(error), ">>> %s file mode: %s open", filename, mode); - perror(error); - return (fd); - } - if (perm_specified) { - if (fchmod(fd, 0664) && (0 == getuid())) { - snprintf(error, sizeof(error), ">>> Could not set mode: %s", filename); - perror(error); - } - } - if (NULL != group) { - group_struct = getgrnam(group); - if (NULL == group) { - snprintf(error, sizeof(error), ">>> Could not get grp number: %s", group); - perror(error); - } else { - if (fchown(fd, -1, group_struct->gr_gid) && (0 == getuid())) { - snprintf(error, sizeof(error), ">>> Could not set group: %s", filename); - perror(error); - } - } - } - /* 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; - } - } else { - snprintf(error, sizeof(error), ">>> %s file mode:%s open", filename, mode); - perror(error); - } - return (fd); -} - -/* Close and unlock file */ -void -file_close(int fd) -{ - if (-1 != fd) { - file_unlock(fd); - close(fd); - } -} - -/* Return length of file */ -long -file_length(int fd) -{ - long pos, len; - pos = file_tell(fd); - len = lseek(fd, 0L, SEEK_END); - lseek(fd, pos, SEEK_SET); - return (len); -} - -/* Zero out file */ -int -file_truncate(int fd) -{ - lseek(fd, 0L, SEEK_SET); - if (ftruncate(fd, 0) < 0) { - perror(">>> file truncate"); - return 0; - } - return 1; -} - -/* Check to see if a file exists Return: 1 success, 0 file not found, -1 error */ -int -file_exist(char *filename, int checkmode) -{ - struct stat mystat; - - /* Verify file exists and is regular file (not sym link) */ - if (checkmode) { - if (-1 == lstat(filename, &mystat)) { - /* file doesn't exist */ - if (ENOENT == errno) { - return 0; - } else { /* permission denied or other error */ - perror(">>> stat file"); - return -1; - } - } - if (!S_ISREG(mystat.st_mode)) - return -1; - - /* Just plain verify the file exists */ - } else { - if (-1 == stat(filename, &mystat)) { - /* file does not exist */ - if (ENOENT == errno) { - return 0; - } else { /* permission denied or other error */ - perror(">>> stat file"); - return -1; - } - } - } - - 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 diff --git a/src/sandbox/Makefile b/src/sandbox/Makefile deleted file mode 100644 index 1216ed999..000000000 --- a/src/sandbox/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# 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> -# -# Modified 15 Apr 2002 Jon Nelson <jnelson@gentoo.org> -# Clean up Makefile somewhat, and use make's implicit rules -# -# $Id: /var/cvsroot/gentoo-src/portage/src/sandbox/Attic/Makefile,v 1.5 2002/08/05 16:44:34 drobbins Exp $ - -.SUFFIXES: -.SUFFIXES: .c .o .so -.PRECIOUS: %.o - -%.so: LIBS=-ldl -%.so: LDFLAGS=--shared -%.so: %.o - $(CC) $(CFLAGS) $(CPPFLAGS) $< -o $@ $(LIBS) $(LDFLAGS) - -CC = gcc -CFLAGS = -Wall -O0 -fPIC -LIBS = -LDFLAGS = - -TARGETS = sandbox libsandbox.so - -all: $(TARGETS) - -clean: - rm -f $(TARGETS) - rm -f *.o *~ diff --git a/src/sandbox/libsandbox.c b/src/sandbox/libsandbox.c deleted file mode 100644 index 342f9e644..000000000 --- a/src/sandbox/libsandbox.c +++ /dev/null @@ -1,873 +0,0 @@ -/* -** Path sandbox for the gentoo linux portage package system, initially -** based on the ROCK Linux Wrapper for getting a list of created files -** -** to integrate with bash, bash should have been built like this -** -** ./configure --prefix=<prefix> --host=<host> --without-gnu-malloc -** -** it's very important that the --enable-static-link option is NOT specified -** -** 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> -** $Id: /var/cvsroot/gentoo-src/portage/src/sandbox/Attic/libsandbox.c,v 1.8 2002/08/05 05:51:39 drobbins Exp $ -*/ - -#define _GNU_SOURCE -#define _REENTRANT - -#define open xxx_open -#define open64 xxx_open64 -# include <dirent.h> -# include <dlfcn.h> -# include <errno.h> -# include <fcntl.h> -# include <stdarg.h> -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -# include <sys/file.h> -# include <sys/stat.h> -# include <sys/types.h> -# include <unistd.h> -# include <utime.h> -#undef open -#undef open64 - -#define PIDS_FILE "/tmp/sandboxpids.tmp" - -typedef struct { - int show_access_violation; - char** deny_prefixes; - int num_deny_prefixes; - char** read_prefixes; - int num_read_prefixes; - char** write_prefixes; - int num_write_prefixes; - char** predict_prefixes; - int num_predict_prefixes; - char** write_denied_prefixes; - int num_write_denied_prefixes; -} sbcontext_t; - -int check_access(sbcontext_t*, const char*, const char*); -int check_syscall(sbcontext_t*, const char*, const char*); -int before_syscall(const char*, const char*); -int before_syscall_open_int(const char*, const char*, int); -int before_syscall_open_char(const char*, const char*, const char*); -void clean_env_entries(char***, int*); -char* filter_path(const char*); -void* get_dl_symbol(char*); -void init_context(sbcontext_t*); -void init_env_entries(char***, int*, char*, int); -int is_sandbox_on(); -int is_sandbox_pid(); - -/* Wrapper macros and functions */ - -/* macro definition to wrap functions before and after the - execution of basic file related system-calls. - - nr : the argument number of the system-call's argument that - contains the file name to monitor - rt : the return type of the system call - name : the name of the function call - arg1, arg2, arg3 : the types of the function call's arguments - fl : the argument number of the system-call's argument that - contains the file access flags - md : the argument number of the system-call's argument that - contains the file access mode -*/ -#define wrsysc3(nr, rt, name, arg1, arg2, arg3) \ - \ -/* the function call is defined externally from this file */ \ -extern rt name(arg1, arg2, arg3); \ - \ -/* orig_ ## name is a pointer to a function with three arguments and the - return type of the system call. This will be used to store the pointer - to the system call function and call it. */ \ -rt (*orig_ ## name)(arg1, arg2, arg3) = NULL; \ - \ -rt name(arg1 a1, arg2 a2, arg3 a3) \ -{ \ - rt result = -1; \ - int old_errno = errno; \ - if (0 == is_sandbox_on() || 1 == before_syscall(#name, a ## nr)) \ - { \ - if (!orig_ ## name) \ - { \ - orig_ ## name = get_dl_symbol(#name); \ - } \ - errno = old_errno; \ - result = orig_ ## name(a1, a2, a3); \ - } \ - return result; \ -} - -#define wrsysc2(nr, rt, name, arg1, arg2) \ -extern rt name(arg1, arg2); \ -rt (*orig_ ## name)(arg1, arg2) = NULL; \ - \ -rt name(arg1 a1, arg2 a2) \ -{ \ - rt result = -1; \ - int old_errno = errno; \ - if (0 == is_sandbox_on() || 1 == before_syscall(#name, a ## nr)) \ - { \ - if (!orig_ ## name) \ - { \ - orig_ ## name = get_dl_symbol(#name); \ - } \ - errno = old_errno; \ - result = orig_ ## name(a1, a2); \ - } \ - return result; \ -} - -#define wrsysc1(nr, rt, name, arg1) \ -extern rt name(arg1); \ -rt (*orig_ ## name)(arg1) = NULL; \ - \ -rt name(arg1 a1) \ -{ \ - rt result = -1; \ - int old_errno = errno; \ - if (0 == is_sandbox_on() || 1 == before_syscall(#name, a ## nr)) \ - { \ - if (!orig_ ## name) \ - { \ - orig_ ## name = get_dl_symbol(#name); \ - } \ - errno = old_errno; \ - result = orig_ ## name(a1); \ - } \ - return result; \ -} - -#define wrsysc1ptr(nr, rt, name, arg1) \ -extern rt name(arg1); \ -rt (*orig_ ## name)(arg1) = NULL; \ - \ -rt name(arg1 a1) \ -{ \ - rt result = NULL; \ - int old_errno = errno; \ - if (0 == is_sandbox_on() || 1 == before_syscall(#name, a ## nr)) \ - { \ - if (!orig_ ## name) \ - { \ - orig_ ## name = get_dl_symbol(#name); \ - } \ - errno = old_errno; \ - result = orig_ ## name(a1); \ - } \ - return result; \ -} - -#define wropenint3(nr, fl, rt, name, arg1, arg2, arg3) \ -extern rt name(arg1, arg2, arg3); \ -rt (*orig_ ## name)(arg1, arg2, arg3) = NULL; \ - \ -rt name(arg1 a1, arg2 a2, arg3 a3) \ -{ \ - rt result = -1; \ - int old_errno = errno; \ - if (0 == is_sandbox_on() || \ - 1 == before_syscall_open_int(#name, a ## nr, a ## fl)) \ - { \ - if (!orig_ ## name) \ - { \ - orig_ ## name = get_dl_symbol(#name); \ - } \ - errno = old_errno; \ - result = orig_ ## name(a1, a2, a3); \ - } \ - return result; \ -} - -#define wropenchar2(nr, md, rt, name, arg1, arg2) \ -extern rt name(arg1, arg2); \ -rt (*orig_ ## name)(arg1, arg2) = NULL; \ - \ -rt name(arg1 a1, arg2 a2) \ -{ \ - rt result = NULL; \ - int old_errno = errno; \ - if (0 == is_sandbox_on() || \ - 1 == before_syscall_open_char(#name, a ## nr, a ## md)) \ - { \ - if (!orig_ ## name) \ - { \ - orig_ ## name = get_dl_symbol(#name); \ - } \ - errno = old_errno; \ - result = orig_ ## name(a1, a2); \ - } \ - return result; \ -} - -#define wropenchar3(nr, md, rt, name, arg1, arg2, arg3) \ -extern rt name(arg1, arg2, arg3); \ -rt (*orig_ ## name)(arg1, arg2, arg3) = NULL; \ - \ -rt name(arg1 a1, arg2 a2, arg3 a3) \ -{ \ - rt result = NULL; \ - int old_errno = errno; \ - if (0 == is_sandbox_on() || \ - 1 == before_syscall_open_char(#name, a ## nr, a ## md)) \ - { \ - if (!orig_ ## name) \ - { \ - orig_ ## name = get_dl_symbol(#name); \ - } \ - errno = old_errno; \ - result = orig_ ## name(a1, a2, a3); \ - } \ - return result; \ -} - -#define wrexec3(nr, rt, name, arg1, arg2, arg3) \ -extern rt name(arg1, arg2, arg3); \ -rt (*orig_ ## name)(arg1, arg2, arg3) = NULL; \ - \ -rt name(arg1 a1, arg2 a2, arg3 a3) \ -{ \ - rt result = -1; \ - int old_errno = errno; \ - if (0 == is_sandbox_on() || 1 == before_syscall(#name, a ## nr)) \ - { \ - if (!orig_ ## name) \ - { \ - orig_ ## name = get_dl_symbol(#name); \ - } \ - errno = old_errno; \ - result = orig_ ## name(a1, a2, a3); \ - } \ - return result; \ -} - -#define wrexec2(nr, rt, name, arg1, arg2) \ -extern rt name(arg1, arg2); \ -rt (*orig_ ## name)(arg1, arg2) = NULL; \ - \ -rt name(arg1 a1, arg2 a2) \ -{ \ - rt result = -1; \ - int old_errno = errno; \ - if (0 == is_sandbox_on() || 1 == before_syscall(#name, a ## nr)) \ - { \ - if (!orig_ ## name) \ - { \ - orig_ ## name = get_dl_symbol(#name); \ - } \ - errno = old_errno; \ - result = orig_ ## name(a1, a2); \ - } \ - return result; \ -} - -#define wrexec2va(nr, rt, name, arg1, arg2) \ -extern rt name(arg1, arg2, ...); \ -rt (*orig_ ## name)(arg1, arg2, ...) = NULL; \ - \ -rt name(arg1 a1, arg2 a2, ...) \ -{ \ - void* result = NULL; \ - int old_errno = errno; \ - if (0 == is_sandbox_on() || 1 == before_syscall(#name, a ## nr)) \ - { \ - if (!orig_ ## name) \ - { \ - orig_ ## name = get_dl_symbol(#name); \ - } \ - errno = old_errno; \ - result = __builtin_apply( (void(*)()) orig_ ## name, \ - __builtin_apply_args(), 32 ); \ - old_errno = errno; \ - } \ - if (NULL == result) \ - { \ - return -1; \ - } \ - else \ - { \ - __builtin_return(result); \ - } \ -} - -wropenint3(1, 2, int, open, const char*, int, mode_t) -wropenint3(1, 2, int, open64, const char*, int, mode_t) - -wropenchar2(1, 2, FILE*, fopen, const char*, const char*) -wropenchar2(1, 2, FILE*, fopen64, const char*, const char*) -wropenchar3(1, 2, FILE*, freopen, const char*, const char*, FILE*) - -wropenchar2(1, 2, FILE*, popen, const char*, const char*) - -// write syscalls - -wrsysc2(1, int, creat, const char*, mode_t) -wrsysc2(1, int, creat64, const char*, mode_t) - -wrsysc2(1, int, mkdir, const char*, mode_t) -wrsysc3(1, int, mknod, const char*, mode_t, dev_t) -wrsysc2(1, int, mkfifo, const char*, mode_t) - -wrsysc2(2, int, link, const char*, const char*) -wrsysc2(2, int, symlink, const char*, const char*) -wrsysc2(2, int, rename, const char*, const char*) - -wrsysc2(1, int, utime, const char*, const struct utimbuf*) -wrsysc2(1, int, utimes, const char*, struct timeval*) - -wrsysc1(1, int, unlink, const char*) -wrsysc1(1, int, rmdir, const char*) - -wrsysc3(1, int, chown, const char*, uid_t, gid_t) -wrsysc3(1, int, lchown, const char*, uid_t, gid_t) - -wrsysc2(1, int, chmod, const char*, mode_t) - -/* read syscalls */ - -wrsysc1ptr(1, DIR*, opendir, const char*) - -/* execution syscalls */ -wrsysc1(1, int, system, const char*) - -wrexec2va(1, int, execl, const char*, const char*) -wrexec2va(1, int, execle, const char*, const char*) -wrexec2(1, int, execv, const char*, char* const*) -wrexec3(1, int, execve, const char*, char* const*, char* const*) -/* execlp is redirected to execvp */ -/* execvp is special since it should search the PATH var entries */ -extern int execvp(const char*, char* const*); -int(*orig_execvp)(const char*, char* const*) = NULL; -int execvp(const char* file, char* const* argv) -{ - int result = -1; - int old_errno = errno; - int i = 0; - int allowed = 1; - char** path_entries = NULL; - int num_path_entries = 0; - char constructed_path[255]; - - if (1 == is_sandbox_on()) - { - init_env_entries(&path_entries, &num_path_entries, "PATH", 0); - for (i = 0; i < num_path_entries; i++) - { - strcpy(constructed_path, path_entries[i]); - strcat(constructed_path, "/"); - strcat(constructed_path, file); - if (0 == before_syscall("execvp", constructed_path)) - { - allowed = 0; - break; - } - } - clean_env_entries(&path_entries, &num_path_entries); - } - - if (1 == allowed) - { - if (!orig_execvp) - { - orig_execvp = get_dl_symbol("execvp"); - } - errno = old_errno; - result = orig_execvp(file, argv); - old_errno = errno; - } - errno = old_errno; - return result; -} - -/* lseek, lseek64, fdopen, fchown, fchmod, fcntl, lockf - are not wrapped since they can't be used if open is wrapped correctly - and unaccessible file descriptors are not possible to create */ - -void* get_dl_symbol(char* symname) -{ - void* result = dlsym(RTLD_NEXT, symname); - if (0 == result) - { - fprintf(stderr, "Sandbox : can't resolve %s: %s.\n", symname, dlerror()); - abort(); - } - return result; -} - -void init_context(sbcontext_t* context) -{ - context->show_access_violation = 1; - context->deny_prefixes = NULL; - context->num_deny_prefixes = 0; - context->read_prefixes = NULL; - context->num_read_prefixes = 0; - context->write_prefixes = NULL; - context->num_write_prefixes = 0; - context->predict_prefixes = NULL; - context->num_predict_prefixes = 0; - context->write_denied_prefixes = NULL; - context->num_write_denied_prefixes = 0; -} - -int is_sandbox_pid() -{ - int result = 0; - FILE* pids_stream = NULL; - int pids_file = -1; - int current_pid = 0; - int tmp_pid = 0; - - pids_stream = fopen(PIDS_FILE, "r"); - if (NULL == pids_stream) - { - perror(">>> pids file fopen"); - } - else - { - pids_file = fileno(pids_stream); - if (pids_file < 0) - { - perror(">>> pids file fileno"); - } - else - { - current_pid = getpid(); - - while (EOF != fscanf(pids_stream, "%d\n", &tmp_pid)) - { - if (tmp_pid == current_pid) - { - result = 1; - break; - } - } - } - if (EOF == fclose(pids_stream)) - { - perror(">>> pids file fclose"); - } - pids_stream = NULL; - pids_file = -1; - } - - return result; -} - -void clean_env_entries(char*** prefixes_array, int* prefixes_num) -{ - int i = 0; - if (NULL != *prefixes_array) - { - for (i = 0; i < *prefixes_num; i++) - { - if (NULL != (*prefixes_array)[i]) - { - free((*prefixes_array)[i]); - (*prefixes_array)[i] = NULL; - } - } - free(*prefixes_array); - *prefixes_array = NULL; - - *prefixes_num = 0; - } -} - -void init_env_entries(char*** prefixes_array, int* prefixes_num, char* env, int warn) -{ - char* prefixes_env = getenv(env); - - if (NULL == prefixes_env) - { - fprintf(stderr, "Sandbox error : the %s environmental variable should be defined.\n", env); - } - else - { - char* buffer = NULL; - int prefixes_env_length = strlen(prefixes_env); - int i = 0; - int num_delimiters = 0; - char* token = NULL; - char* prefix = NULL; - - for (i = 0; i < prefixes_env_length; i++) - { - if (':' == prefixes_env[i]) - { - num_delimiters++; - } - } - - if (num_delimiters > 0) - { - buffer = (char*)malloc(sizeof(char)*(prefixes_env_length+1)); - *prefixes_array = (char**)malloc(sizeof(char*)*(num_delimiters+1)); - - strcpy(buffer, prefixes_env); - token = strtok(buffer, ":"); - while (NULL != token && - strlen(token) > 0) - { - prefix = (char*)malloc(sizeof(char)*(strlen(token)+1)); - strcpy(prefix, token); - (*prefixes_array)[(*prefixes_num)++] = filter_path(prefix); - free(prefix); - token = strtok(NULL, ":"); - } - free(buffer); - buffer = NULL; - } - else if(prefixes_env_length > 0) - { - (*prefixes_array) = (char**)malloc(sizeof(char*)); - - prefix = (char*)malloc(sizeof(char)*(prefixes_env_length+1)); - strcpy(prefix, prefixes_env); - (*prefixes_array)[(*prefixes_num)++] = filter_path(prefix); - free(prefix); - } - } -} - -char* filter_path(const char* path) -{ - int initial_path_length = strlen(path); - char* filtered_path = (char*)malloc(sizeof(char)*(initial_path_length+1)); - int i = 0; - int j = 0; - - for (i = 0, j = 0; i < initial_path_length;) - { - filtered_path[j] = path[i]; - if ('/' == filtered_path[j]) - { - while ('/' == path[i] && - i < initial_path_length) - { - i++; - } - } - else - { - i++; - } - j++; - } - filtered_path[j] = 0; - - return filtered_path; -} - -int check_access(sbcontext_t* sbcontext, const char* func, const char* path) -{ - int result = -1; - int i = 0; - char* filtered_path = filter_path(path); - - if ('/' != path[0]) - { - return 0; - } - - if (0 == strcmp(filtered_path, "/etc/ld.so.preload") && - is_sandbox_pid()) - { - result = 1; - } - - if (-1 == result) - { - if (NULL != sbcontext->deny_prefixes) - { - for (i = 0; i < sbcontext->num_deny_prefixes; i++) - { - if (0 == strncmp(filtered_path, sbcontext->deny_prefixes[i], strlen(sbcontext->deny_prefixes[i]))) - { - result = 0; - break; - } - } - } - - if (-1 == result) - { - if (NULL != sbcontext->read_prefixes && - (0 == strcmp(func, "open_rd") || - 0 == strcmp(func, "popen") || - 0 == strcmp(func, "opendir") || - 0 == strcmp(func, "system") || - 0 == strcmp(func, "execl") || - 0 == strcmp(func, "execlp") || - 0 == strcmp(func, "execle") || - 0 == strcmp(func, "execv") || - 0 == strcmp(func, "execvp") || - 0 == strcmp(func, "execve"))) - { - for (i = 0; i < sbcontext->num_read_prefixes; i++) - { - if (0 == strncmp(filtered_path, sbcontext->read_prefixes[i], strlen(sbcontext->read_prefixes[i]))) - { - result = 1; - break; - } - } - } - else if (NULL != sbcontext->write_prefixes && - (0 == strcmp(func, "open_wr") || - 0 == strcmp(func, "creat") || - 0 == strcmp(func, "creat64") || - 0 == strcmp(func, "mkdir") || - 0 == strcmp(func, "mknod") || - 0 == strcmp(func, "mkfifo") || - 0 == strcmp(func, "link") || - 0 == strcmp(func, "symlink") || - 0 == strcmp(func, "rename") || - 0 == strcmp(func, "utime") || - 0 == strcmp(func, "utimes") || - 0 == strcmp(func, "unlink") || - 0 == strcmp(func, "rmdir") || - 0 == strcmp(func, "chown") || - 0 == strcmp(func, "lchown") || - 0 == strcmp(func, "chmod"))) - { - struct stat tmp_stat; - - for (i = 0; i < sbcontext->num_write_denied_prefixes; i++) - { - if (0 == strncmp(filtered_path, sbcontext->write_denied_prefixes[i], strlen(sbcontext->write_denied_prefixes[i]))) - { - result = 0; - break; - } - } - if (-1 == result) - { - for (i = 0; i < sbcontext->num_write_prefixes; i++) - { - if (0 == strncmp(filtered_path, sbcontext->write_prefixes[i], strlen(sbcontext->write_prefixes[i]))) - { - result = 1; - break; - } - } - - if (-1 == result) - { - /* hack to prevent mkdir of existing dirs to show errors */ - if (strcmp(func, "mkdir") == 0) - { - if (0 == stat(filtered_path, &tmp_stat)) - { - sbcontext->show_access_violation = 0; - result = 0; - } - } - - if (-1 == result) - { - for (i = 0; i < sbcontext->num_predict_prefixes; i++) - { - if (0 == strncmp(filtered_path, sbcontext->predict_prefixes[i], strlen(sbcontext->predict_prefixes[i]))) - { - sbcontext->show_access_violation = 0; - result = 0; - break; - } - } - } - } - } - } - } - } - - if (-1 == result) - { - result = 0; - } - - free(filtered_path); - - return result; -} - -int check_syscall(sbcontext_t* sbcontext, const char* func, const char* file) -{ - int result = 1; - char* absolute_path = NULL; - char* tmp_buffer = NULL; - struct stat log_stat; - char* log_path = NULL; - int log_file = 0; - struct stat debug_log_stat; - char* debug_log_env = NULL; - char* debug_log_path = NULL; - int debug_log_file = 0; - char buffer[512]; - - if ('/' == file[0]) - { - absolute_path = (char*)malloc(sizeof(char)*(strlen(file)+1)); - sprintf(absolute_path, "%s", file); - } - else - { - tmp_buffer = get_current_dir_name(); - absolute_path = (char*)malloc(sizeof(char)*(strlen(tmp_buffer)+1+strlen(file)+1)); - sprintf(absolute_path,"%s/%s", tmp_buffer, file); - free(tmp_buffer); - tmp_buffer = NULL; - } - - log_path = getenv("SANDBOX_LOG"); - debug_log_env = getenv("SANDBOX_DEBUG"); - debug_log_path = getenv("SANDBOX_DEBUG_LOG"); - - if ((NULL == log_path || 0 != strcmp(absolute_path, log_path)) && - (NULL == debug_log_env || NULL == debug_log_path || 0 != strcmp(absolute_path, debug_log_path)) && - 0 == check_access(sbcontext, func, absolute_path)) - { - if (1 == sbcontext->show_access_violation) - { - fprintf(stderr, "\e[31;01mACCESS DENIED\033[0m %s:%*s%s\n", func, (int)(10-strlen(func)), "", absolute_path); - - if (NULL != log_path) - { - sprintf(buffer, "%s:%*s%s\n", func, (int)(10-strlen(func)), "", absolute_path); - if (0 == lstat(log_path, &log_stat) && - 0 == S_ISREG(log_stat.st_mode)) - { - fprintf(stderr, "\e[31;01mSECURITY BREACH\033[0m %s already exists and is not a regular file.\n", log_path); - } - else - { - log_file = open(log_path, O_APPEND|O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - if(log_file >= 0) - { - write(log_file, buffer, strlen(buffer)); - close(log_file); - } - } - } - } - - result = 0; - } - else if (NULL != debug_log_env) - { - if (NULL != debug_log_path) - { - if (0 != strcmp(absolute_path, debug_log_path)) - { - sprintf(buffer, "%s:%*s%s\n", func, (int)(10-strlen(func)), "", absolute_path); - if (0 == lstat(debug_log_path, &debug_log_stat) && - 0 == S_ISREG(debug_log_stat.st_mode)) - { - fprintf(stderr, "\e[31;01mSECURITY BREACH\033[0m %s already exists and is not a regular file.\n", log_path); - } - else - { - debug_log_file = open(debug_log_path, O_APPEND|O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - if(debug_log_file >= 0) - { - write(debug_log_file, buffer, strlen(buffer)); - close(debug_log_file); - } - } - } - } - else - { - fprintf(stderr, "\e[32;01mACCESS ALLOWED\033[0m %s:%*s%s\n", func, (int)(10-strlen(func)), "", absolute_path); - } - } - - free(absolute_path); - absolute_path = NULL; - - return result; -} - -int is_sandbox_on() -{ - /* $SANDBOX_ACTIVE is an env variable that should ONLY - * be used internal by sandbox.c and libsanbox.c. External - * sources should NEVER set it, else the sandbox is enabled - * in some cases when run in parallel with another sandbox, - * but not even in the sandbox shell. - * - * Azarah (3 Aug 2002) - */ - if (NULL != getenv("SANDBOX_ON") && - 0 == strcmp(getenv("SANDBOX_ON"), "1") && - NULL != getenv("SANDBOX_ACTIVE") && - 0 == strcmp(getenv("SANDBOX_ACTIVE"), "armedandready")) - { - return 1; - } - else - { - return 0; - } -} - -int before_syscall(const char* func, const char* file) -{ - int result = 1; - - sbcontext_t sbcontext; - - init_context(&sbcontext); - - init_env_entries(&(sbcontext.deny_prefixes), &(sbcontext.num_deny_prefixes), "SANDBOX_DENY", 1); - init_env_entries(&(sbcontext.read_prefixes), &(sbcontext.num_read_prefixes), "SANDBOX_READ", 1); - init_env_entries(&(sbcontext.write_prefixes), &(sbcontext.num_write_prefixes), "SANDBOX_WRITE", 1); - init_env_entries(&(sbcontext.predict_prefixes), &(sbcontext.num_predict_prefixes), "SANDBOX_PREDICT", 1); - - result = check_syscall(&sbcontext, func, file); - - clean_env_entries(&(sbcontext.deny_prefixes), &(sbcontext.num_deny_prefixes)); - clean_env_entries(&(sbcontext.read_prefixes), &(sbcontext.num_read_prefixes)); - clean_env_entries(&(sbcontext.write_prefixes), &(sbcontext.num_write_prefixes)); - clean_env_entries(&(sbcontext.predict_prefixes), &(sbcontext.num_predict_prefixes)); - - if (0 == result) - { - errno = EACCES; - } - - return result; -} - -int before_syscall_open_int(const char* func, const char* file, int flags) -{ - if (flags & O_WRONLY || - flags & O_RDWR) - { - return before_syscall("open_wr", file); - } - else - { - return before_syscall("open_rd", file); - } -} - -int before_syscall_open_char(const char* func, const char* file, const char* mode) -{ - if (strcmp(mode, "r") == 0 || - strcmp(mode, "rb") == 0) - { - return before_syscall("open_rd", file); - } - else - { - return before_syscall("open_wr", file); - } -} diff --git a/src/sandbox/problems/Makefile b/src/sandbox/problems/Makefile deleted file mode 100644 index e24710826..000000000 --- a/src/sandbox/problems/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# 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> -# -# Modified 15 Apr 2002 Jon Nelson <jnelson@gentoo.org> -# Clean up Makefile somewhat, and use make's implicit rules -# -# $Id: /var/cvsroot/gentoo-src/portage/src/sandbox/problems/Attic/Makefile,v 1.2 2002/04/16 01:06:55 jnelson Exp $ - -.SUFFIXES: -.SUFFIXES: .c .o .so -.PRECIOUS: %.o - -%.so: LIBS=-ldl -%.so: LDFLAGS=--shared -%.so: %.o - $(CC) $(CFLAGS) $(CPPFLAGS) $< -o $@ $(LIBS) $(LDFLAGS) - -CC = gcc -CFLAGS = -Wall -O2 -LIBS = -LDFLAGS = - -TARGETS = sandbox_muttbug sandbox_dev_fd_foo \ - libsandbox_muttbug.so libsandbox_emacsbug.so - -all: $(TARGETS) - -clean: - rm -f $(TARGETS) - rm -f *.o *~ diff --git a/src/sandbox/problems/libsandbox_emacsbug.c b/src/sandbox/problems/libsandbox_emacsbug.c deleted file mode 100644 index 0742bcdc1..000000000 --- a/src/sandbox/problems/libsandbox_emacsbug.c +++ /dev/null @@ -1,34 +0,0 @@ -/* $Id: /var/cvsroot/gentoo-src/portage/src/sandbox/problems/Attic/libsandbox_emacsbug.c,v 1.2 2003/03/22 14:24:38 carpaski Exp $ */ - -#define _GNU_SOURCE -#define _REENTRANT - -#define open xxx_open -# include <dlfcn.h> -# include <errno.h> -# include <fcntl.h> -# include <stdlib.h> -# include <sys/stat.h> -# include <sys/types.h> -#undef open - -extern int open(const char*, int, mode_t); -int (*orig_open)(const char*, int, mode_t) = NULL; -int open(const char* pathname, int flags, mode_t mode) -{ - int old_errno = errno; - - /* code that makes xemacs' compilation produce a segfaulting executable */ -/* char** test = NULL; - test = (char**)malloc(sizeof(char*)); - free(test);*/ - /* end of that code */ - - if (!orig_open) - { - orig_open = dlsym(RTLD_NEXT, "open"); - } - errno = old_errno; - return orig_open(pathname, flags, mode); -} - diff --git a/src/sandbox/problems/libsandbox_muttbug.c b/src/sandbox/problems/libsandbox_muttbug.c deleted file mode 100644 index 08a798654..000000000 --- a/src/sandbox/problems/libsandbox_muttbug.c +++ /dev/null @@ -1,24 +0,0 @@ -/* $Id: /var/cvsroot/gentoo-src/portage/src/sandbox/problems/Attic/libsandbox_muttbug.c,v 1.2 2003/03/22 14:24:38 carpaski Exp $ */ - -#define _GNU_SOURCE -#define _REENTRANT - -#define open xxx_open -#include <dlfcn.h> -#include <errno.h> -#include <stdio.h> -#undef open - -extern FILE* fopen(const char*, const char*); -FILE* (*orig_fopen)(const char*, const char*) = 0; -FILE* fopen(const char* a1, const char* a2) -{ - int old_errno = errno; - if (!orig_fopen) - { - orig_fopen = dlsym(RTLD_NEXT, "fopen"); - } - errno = old_errno; - return orig_fopen(a1, a2); -} - diff --git a/src/sandbox/problems/sandbox_dev_fd_foo.c b/src/sandbox/problems/sandbox_dev_fd_foo.c deleted file mode 100644 index 276f2ba6e..000000000 --- a/src/sandbox/problems/sandbox_dev_fd_foo.c +++ /dev/null @@ -1,42 +0,0 @@ -/* $Id: /var/cvsroot/gentoo-src/portage/src/sandbox/problems/Attic/sandbox_dev_fd_foo.c,v 1.2 2003/03/22 14:24:38 carpaski Exp $ */ - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -void cleanup_1(void) -{ - puts("Unlinking file..."); - unlink("/tmp/_sandbox_test.file"); -} - -int main(void) -{ - struct stat s1, s2; - FILE *fp1, *fp2; - char *file = "/tmp/_sandbox_test.file"; - char devfd[32]; - - printf("Opening file...\n"); - if (!(fp1 = fopen(file, "w"))) - exit(1); - atexit(cleanup_1); - printf("fstat'ing file...\n"); - if (fstat(fileno(fp1), &s1) < 0) - exit(2); - sprintf(devfd, "/dev/fd/%d", fileno(fp1)); - printf("fopening %s...\n", devfd); - if (!(fp2 = fopen(devfd, "w"))) - exit(3); - printf("fstat'ing %s...\n", devfd); - if (fstat(fileno(fp2), &s2) < 0) - exit(4); - printf("Checking %ld == %ld and %ld == %ld...\n", - (long int) s1.st_dev, (long int) s2.st_dev, s1.st_ino, s2.st_ino); - if (s1.st_dev != s2.st_dev || s1.st_ino != s2.st_ino) - exit(5); - printf("Success!\n"); - return(0); -} diff --git a/src/sandbox/problems/sandbox_muttbug.c b/src/sandbox/problems/sandbox_muttbug.c deleted file mode 100644 index a643f66aa..000000000 --- a/src/sandbox/problems/sandbox_muttbug.c +++ /dev/null @@ -1,43 +0,0 @@ -/* $Id: /var/cvsroot/gentoo-src/portage/src/sandbox/problems/Attic/sandbox_muttbug.c,v 1.3 2003/03/22 14:24:38 carpaski Exp $ */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -int main(int argc, char *argv[]) -{ - FILE *fd ; - - printf("unlink\n"); - unlink("/tmp/test"); - printf("... done\n"); - - printf("fopen\n"); - fd = fopen("/tmp/test", "a+"); - printf("... done\n"); - - printf("fputc\n"); - fputc('7', fd); - printf("... done\n"); - - printf("fseek\n"); - fseek(fd, 0, SEEK_SET); - printf("... done\n"); - - printf("freopen\n"); - fd = freopen("/tmp/test", "r", fd); - printf("... done\n"); - - printf("fgetc "); - printf("%c\n", fgetc(fd)); - printf("... done\n"); - - printf("fseek\n"); - fseek(fd, 0, SEEK_SET); - printf("... done\n"); - - printf("fclose\n"); - fclose(fd); - printf("... done\n"); - return 0; -} diff --git a/src/sandbox/sandbox.bashrc b/src/sandbox/sandbox.bashrc deleted file mode 100644 index a2e2a7a8f..000000000 --- a/src/sandbox/sandbox.bashrc +++ /dev/null @@ -1,8 +0,0 @@ -# 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> -# $Id: /var/cvsroot/gentoo-src/portage/src/sandbox/Attic/sandbox.bashrc,v 1.2 2002/03/06 09:51:02 gbevin Exp $ -source /etc/profile -export LD_PRELOAD="$SANDBOX_LIB" -alias make="make LD_PRELOAD=$SANDBOX_LIB" -alias su="su -c '/bin/bash -rcfile $SANDBOX_DIR/sandbox.bashrc'" diff --git a/src/sandbox/sandbox.c b/src/sandbox/sandbox.c deleted file mode 100644 index c8a26a9f5..000000000 --- a/src/sandbox/sandbox.c +++ /dev/null @@ -1,921 +0,0 @@ -/* -** Path sandbox for the gentoo linux portage package system, initially -** based on the ROCK Linux Wrapper for getting a list of created files -** -** to integrate with bash, bash should have been built like this -** -** ./configure --prefix=<prefix> --host=<host> --without-gnu-malloc -** -** it's very important that the --enable-static-link option is NOT specified -** -** 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> -** $Id: /var/cvsroot/gentoo-src/portage/src/sandbox/Attic/sandbox.c,v 1.13 2002/08/05 05:51:39 drobbins Exp $ -*/ - -#define _GNU_SOURCE - -#include <errno.h> -#include <fcntl.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> -#include <string.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/resource.h> -#include <sys/wait.h> -#include <unistd.h> - -#define LD_PRELOAD_FILE "/etc/ld.so.preload" -#define LIB_NAME "libsandbox.so" -#define BASHRC_NAME "sandbox.bashrc" -#define PIDS_FILE "/tmp/sandboxpids.tmp" -#define LOG_FILE_PREFIX "/tmp/sandbox-" -#define DEBUG_LOG_FILE_PREFIX "/tmp/sandbox-debug-" -#define LOG_FILE_EXT ".log" - -#define ENV_SANDBOX_DEBUG_LOG "SANDBOX_DEBUG_LOG" -#define ENV_SANDBOX_LOG "SANDBOX_LOG" -#define ENV_SANDBOX_DIR "SANDBOX_DIR" -#define ENV_SANDBOX_LIB "SANDBOX_LIB" - -#define ENV_SANDBOX_DENY "SANDBOX_DENY" -#define ENV_SANDBOX_READ "SANDBOX_READ" -#define ENV_SANDBOX_WRITE "SANDBOX_WRITE" -#define ENV_SANDBOX_PREDICT "SANDBOX_PREDICT" - -#define ENV_SANDBOX_ON "SANDBOX_ON" -#define ENV_SANDBOX_BEEP "SANDBOX_BEEP" - -#define DEFAULT_BEEP_COUNT 3 - -int preload_adaptable = 1; -int cleaned_up = 0; - -char* dirname(const char* path) -{ - char* base = NULL; - unsigned int length = 0; - - base = strrchr(path, '/'); - if (NULL == base) - { - return strdup("."); - } - while (base > path && - *base == '/') - { - base--; - } - length = (unsigned int) 1 + base - path; - - base = malloc(sizeof(char)*(length+1)); - memmove(base, path, length); - base[length] = 0; - - return base; -} - -void cleanup() -{ - int i = 0; - int success = 1; - - FILE* preload_stream = NULL; - int preload_file = -1; - char preload_entry[255]; - char** preload_array = NULL; - int num_of_preloads = 0; - - FILE* pids_stream = NULL; - struct stat pids_stat; - int pids_file = -1; - char pid_string[255]; - int tmp_pid = 0; - int* pids_array = NULL; - int num_of_pids = 0; - - /* remove this sandbox's bash pid from the global pids file if it has rights to adapt the ld.so.preload file*/ - if (1 == preload_adaptable && - 0 == cleaned_up) - { - cleaned_up = 1; - success = 1; - if (0 == lstat(PIDS_FILE, &pids_stat) && - 0 == S_ISREG(pids_stat.st_mode)) - { - perror(">>> pids file is not a regular file"); - success = 0; - } - else - { - pids_stream = fopen(PIDS_FILE, "r+"); - if (NULL == pids_stream) - { - perror(">>> pids file fopen"); - success = 0; - } - else - { - pids_file = fileno(pids_stream); - if (pids_file < 0) - { - perror(">>> pids file fileno"); - success = 0; - } - else - { - if (flock(pids_file, LOCK_EX) < 0) - { - perror(">>> pids file lock"); - success = 0; - } - else - { - /* check which sandbox pids are still running */ - while (EOF != fscanf(pids_stream, "%d\n", &tmp_pid)) - { - if (0 == kill(tmp_pid, 0)) - { - if (NULL == pids_array) - { - pids_array = (int*)malloc(sizeof(int)); - } - else - { - pids_array = (int*)realloc(pids_array, sizeof(int)*(num_of_pids+1)); - } - pids_array[num_of_pids++] = tmp_pid; - } - } - - /* clean the /etc/ld.so.preload file if no other sandbox processes are running anymore*/ - if(num_of_pids == 1) - { - success = 1; - preload_stream = fopen("/etc/ld.so.preload", "r+"); - if (NULL == preload_stream) - { - perror(">>> /etc/ld.so.preload file fopen"); - success = 0; - } - else - { - preload_file = fileno(preload_stream); - if (preload_file < 0) - { - perror(">>> /etc/ld.so.preload file fileno"); - success = 0; - } - else - { - if (flock(preload_file, LOCK_EX) < 0) - { - perror(">>> /etc/ld.so.preload file lock"); - success = 0; - } - else - { - /* only get the entries that don't contain the sandbox library from the /etc/ld.so.preload file */ - while (EOF != fscanf(preload_stream, "%s\n", preload_entry)) - { - if (NULL == strstr(preload_entry, LIB_NAME)) - { - if (NULL == preload_array) - { - preload_array = (char**)malloc(sizeof(char*)); - } - else - { - preload_array = (char**)realloc(pids_array, sizeof(char*)*(num_of_preloads+1)); - } - preload_array[num_of_preloads++] = strdup(preload_entry); - } - } - - if (fseek(preload_stream, 0, SEEK_SET) < 0) - { - perror(">>> /etc/ld.so.preload file fseek"); - success = 0; - } - else - { - /* empty the /etc/ld.so.preload file */ - if (ftruncate(preload_file, 0) < 0) - { - perror(">>> /etc/ld.so.preload file ftruncate"); - success = 0; - } - else - { - /* store the other preload libraries back into the /etc/ld.so.preload file */ - if(num_of_preloads > 0) - { - for (i = 0; i < num_of_preloads; i++) - { - sprintf(preload_entry, "%s\n", preload_array[i]); - if (write(preload_file, preload_entry, strlen(preload_entry)) != strlen(preload_entry)) - { - perror(">>> /etc/ld.so.preload file write"); - success = 0; - break; - } - } - } - } - } - - if (NULL != preload_array) - { - for (i = 0; i < num_of_preloads; i++) - { - free(preload_array[i]); - preload_array[i] = NULL; - } - free(preload_array); - preload_array = NULL; - } - - if (flock(preload_file, LOCK_UN) < 0) - { - perror(">>> /etc/ld.so.preload file unlock"); - success = 0; - } - } - } - if (EOF == fclose(preload_stream)) - { - perror(">>> /etc/ld.so.preload file fclose"); - success = 0; - } - preload_stream = NULL; - preload_file = -1; - } - } - - if (fseek(pids_stream, 0, SEEK_SET) < 0) - { - perror(">>> pids file fseek"); - success = 0; - } - else - { - /* empty the pids file */ - if (ftruncate(pids_file, 0) < 0) - { - perror(">>> pids file ftruncate"); - success = 0; - } - else - { - /* if pids are still running, write only the running pids back to the file */ - if(num_of_pids > 1) - { - for (i = 0; i < num_of_pids; i++) - { - sprintf(pid_string, "%d\n", pids_array[i]); - if (write(pids_file, pid_string, strlen(pid_string)) != strlen(pid_string)) - { - perror(">>> pids file write"); - success = 0; - break; - } - } - } - } - } - - if (NULL != pids_array) - { - free(pids_array); - pids_array = NULL; - } - - if (flock(pids_file, LOCK_UN) < 0) - { - perror(">>> pids file unlock"); - success = 0; - } - } - } - if (EOF == fclose(pids_stream)) - { - perror(">>> pids file fclose"); - success = 0; - } - pids_stream = NULL; - pids_file = -1; - } - } - if (0 == success) - { - exit(1); - } - } -} - -void stop(int signum) -{ - cleanup(); -} - -int main(int argc, char** argv) -{ - int i = 0; - int success = 1; - int status = 0; - char* run_str = "-c"; - char run_arg[255]; - - struct stat preload_stat; - FILE* preload_stream = NULL; - int preload_file = -1; - char preload_entry[255]; - int preload_lib_present = 0; - - int bash_pid = 0; - char* home_dir = NULL; - char portage_tmp_dir[PATH_MAX]; - char var_tmp_dir[PATH_MAX]; - char tmp_dir[PATH_MAX]; - char sandbox_write_var[255]; - char sandbox_predict_var[255]; - char* tmp_string = NULL; - char full_sandbox_path[255]; - char sandbox_log[255]; - char* sandbox_log_env; - struct stat sandbox_log_stat; - int sandbox_log_presence = 0; - int sandbox_log_file = -1; - char sandbox_debug_log[255]; - char sandbox_dir[255]; - char sandbox_lib[255]; - struct stat sandbox_lib_stat; - char sandbox_rc[255]; - struct stat sandbox_rc_stat; - - struct stat pids_stat; - int pids_file = -1; - char pid_string[255]; - - // Only print info if called with no arguments .... - if (argc < 2) - { - printf("========================== Gentoo linux path sandbox ===========================\n"); - } - - /* check if a sandbox is already running */ - if (NULL != getenv(ENV_SANDBOX_ON)) - { - fprintf(stderr, "Not launching a new sandbox instance\nAnother one is already running in this process hierarchy.\n"); - - exit(1); - } - else - { - char* argv_bash[] = - { - "/bin/bash", - "-rcfile", - NULL, - NULL, - NULL, - NULL - }; - - /* determine the location of all the sandbox support files */ - if (argc < 2) - printf("Detection of the support files.\n"); - if ('/' == argv[0][0]) - { - strcpy(full_sandbox_path, argv[0]); - } - else - { - tmp_string = get_current_dir_name(); - strcpy(full_sandbox_path, tmp_string); - free(tmp_string); - tmp_string = NULL; - strcat(full_sandbox_path, "/"); - strcat(full_sandbox_path, argv[0]); - } - tmp_string = dirname(full_sandbox_path); - strcpy(sandbox_dir, tmp_string); - free(tmp_string); - tmp_string = NULL; - strcat(sandbox_dir, "/"); - strcpy(sandbox_lib, "/lib/"); - strcat(sandbox_lib, LIB_NAME); - if (-1 == stat(sandbox_lib, &sandbox_lib_stat)) - { - strcpy(sandbox_lib, sandbox_dir); - strcat(sandbox_lib, LIB_NAME); - } - strcpy(sandbox_rc, "/usr/lib/portage/lib/"); - strcat(sandbox_rc, BASHRC_NAME); - if (-1 == stat(sandbox_rc, &sandbox_rc_stat)) - { - strcpy(sandbox_rc, sandbox_dir); - strcat(sandbox_rc, BASHRC_NAME); - } - - /* verify the existance of required files */ - if (argc < 2) - { - printf("Verification of the required files.\n"); - } - if (-1 == stat(sandbox_lib, &sandbox_lib_stat)) - { - fprintf(stderr, "Could not open the sandbox library at '%s'.\n", sandbox_lib); - return -1; - } - else if (-1 == stat(sandbox_rc, &sandbox_rc_stat)) - { - fprintf(stderr, "Could not open the sandbox rc file at '%s'.\n", sandbox_rc); - return -1; - } - else - { - /* ensure that the /etc/ld.so.preload file contains an entry for the sandbox lib */ - if (argc < 2) - { - printf("Setting up the ld.so.preload file.\n"); - } - - /* check if the /etc/ld.so.preload file exists */ - if (stat("/etc/ld.so.preload", &preload_stat) < 0 && - ENOENT == errno) - { - /* if not, try to create it and write the path of the sandbox lib to it */ - success = 1; - preload_file = open("/etc/ld.so.preload", O_WRONLY|O_CREAT, 0644); - if (preload_file < 0) - { - /* if access was denied, warn the user about it */ - if (EACCES == errno) - { - preload_adaptable = 0; - printf(">>> Couldn't adapt the /etc/ld.so.preload file.\n>>> It's possible that not all function calls are trapped\n"); - } - else - { - perror(">>> /etc/ld.so.preload file open"); - success = 0; - } - } - else - { - if (flock(preload_file, LOCK_EX) < 0) - { - perror(">>> /etc/ld.so.preload file lock"); - success = 0; - } - else - { - if (write(preload_file, sandbox_lib, strlen(sandbox_lib)) != strlen(sandbox_lib)) - { - perror(">>> /etc/ld.so.preload file write"); - success = 0; - } - - if (flock(preload_file, LOCK_UN) < 0) - { - perror(">>> /etc/ld.so.preload file unlock"); - success = 0; - } - } - if (close(preload_file) < 0) - { - perror(">>> /etc/ld.so.preload file close"); - success = 0; - } - pids_file = -1; - } - if (0 == success) - { - exit(1); - } - } - else - { - /* if the /etc/ld.so.preload file exists, try to open it in read/write mode */ - success = 1; - if (0 == S_ISREG(preload_stat.st_mode)) - { - perror(">>> /etc/ld.so.preload file is not a regular file"); - success = 0; - } - else - { - preload_stream = fopen("/etc/ld.so.preload", "r+"); - if (NULL == preload_stream) - { - if (EACCES == errno) - { - /* if access was denied, warn the user about it */ - preload_adaptable = 0; - printf(">>> Couldn't adapt the /etc/ld.so.preload file.\n>>> It's possible that not all function calls are trapped\n"); - } - else - { - perror(">>> /etc/ld.so.preload file fopen"); - success = 0; - } - } - else - { - preload_file = fileno(preload_stream); - if (preload_file < 0) - { - perror(">>> /etc/ld.so.preload file fileno"); - success = 0; - } - else - { - if (flock(preload_file, LOCK_EX) < 0) - { - perror(">>> /etc/ld.so.preload file lock"); - success = 0; - } - else - { - /* check if the sandbox library is already present in the /etc/ld.so.preload file */ - while (EOF != fscanf(preload_stream, "%s\n", preload_entry)) - { - if (NULL != strstr(preload_entry, LIB_NAME)) - { - preload_lib_present = 1; - break; - } - } - - /* if it's not present, add the sandbox lib path to the end of the /etc/ld.so.preload file */ - if (0 == preload_lib_present) - { - if (fseek(preload_stream, 0, SEEK_END) < 0) - { - perror(">>> /etc/ld.so.preload file fseek"); - success = 0; - } - else - { - if (write(preload_file, sandbox_lib, strlen(sandbox_lib)) != strlen(sandbox_lib)) - { - perror(">>> /etc/ld.so.preload file write"); - success = 0; - } - } - } - - if (flock(preload_file, LOCK_UN) < 0) - { - perror(">>> /etc/ld.so.preload file unlock"); - success = 0; - } - } - } - if (EOF == fclose(preload_stream)) - { - perror(">>> /etc/ld.so.preload file fclose"); - success = 0; - } - preload_stream = NULL; - preload_file = -1; - } - } - if (0 == success) - { - exit(1); - } - } - - /* set up the required environment variables */ - if (argc < 2) - { - printf("Setting up the required environment variables.\n"); - } - argv_bash[2] = sandbox_rc; - - sprintf(pid_string, "%d", getpid()); - strcpy(sandbox_log, LOG_FILE_PREFIX); - sandbox_log_env = getenv(ENV_SANDBOX_LOG); - if (sandbox_log_env) - { - strcat(sandbox_log, sandbox_log_env); - strcat(sandbox_log, "-"); - } - strcat(sandbox_log, pid_string); - strcat(sandbox_log, LOG_FILE_EXT); - setenv(ENV_SANDBOX_LOG, sandbox_log, 1); - strcpy(sandbox_debug_log, DEBUG_LOG_FILE_PREFIX); - strcat(sandbox_debug_log, pid_string); - strcat(sandbox_debug_log, LOG_FILE_EXT); - setenv(ENV_SANDBOX_DEBUG_LOG, sandbox_debug_log, 1); - home_dir = getenv("HOME"); - - // drobbins: we need to expand these paths using realpath() so that PORTAGE_TMPDIR - // can contain symlinks (example, /var is a symlink, /var/tmp is a symlink.) Without - // this, access is denied to /var/tmp, hurtin' ebuilds. - - realpath(getenv("PORTAGE_TMPDIR"),portage_tmp_dir); - realpath("/var/tmp",var_tmp_dir); - realpath("/tmp",tmp_dir); - - setenv(ENV_SANDBOX_DIR, sandbox_dir, 1); - setenv(ENV_SANDBOX_LIB, sandbox_lib, 1); - setenv("LD_PRELOAD", sandbox_lib, 1); - if (NULL == getenv(ENV_SANDBOX_DENY)) - { - setenv(ENV_SANDBOX_DENY, LD_PRELOAD_FILE, 1); - } - if (NULL == getenv(ENV_SANDBOX_READ)) - { - setenv(ENV_SANDBOX_READ, "/", 1); - } - if (NULL == getenv(ENV_SANDBOX_WRITE)) - { - /* these should go into make.globals later on */ - strcpy(sandbox_write_var, ""); - strcat(sandbox_write_var, "/dev/zero:/dev/fd/:/dev/null:/dev/pts/:/dev/vc/:/dev/tty:/tmp/"); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, "/var/log/scrollkeeper.log"); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, home_dir); - strcat(sandbox_write_var, "/.gconfd/lock"); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, home_dir); - strcat(sandbox_write_var, "/.bash_history"); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, "/usr/tmp/conftest"); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, "/usr/lib/conftest"); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, "/usr/tmp/cf"); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, "/usr/lib/cf"); - strcat(sandbox_write_var, ":"); - if (NULL == portage_tmp_dir) - { - strcat(sandbox_write_var, tmp_dir); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, var_tmp_dir); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, "/tmp/"); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, "/var/tmp/"); - } - else if (0 == strcmp(sandbox_write_var, "/var/tmp/")) - { - strcat(sandbox_write_var, portage_tmp_dir); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, tmp_dir); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, "/tmp/"); - } - else if (0 == strcmp(sandbox_write_var, "/tmp/")) - { - strcat(sandbox_write_var, portage_tmp_dir); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, var_tmp_dir); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, "/var/tmp/"); - } - else - { - strcat(sandbox_write_var, portage_tmp_dir); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, tmp_dir); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, var_tmp_dir); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, "/tmp/"); - strcat(sandbox_write_var, ":"); - strcat(sandbox_write_var, "/var/tmp/"); - } - /* */ - setenv(ENV_SANDBOX_WRITE, sandbox_write_var, 1); - } - if (NULL == getenv(ENV_SANDBOX_PREDICT)) - { - /* these should go into make.globals later on */ - strcpy(sandbox_predict_var, ""); - strcat(sandbox_predict_var, home_dir); - strcat(sandbox_predict_var, "/."); - strcat(sandbox_predict_var, ":"); - strcat(sandbox_predict_var, "/usr/lib/python2.0/"); - strcat(sandbox_predict_var, ":"); - strcat(sandbox_predict_var, "/usr/lib/python2.1/"); - strcat(sandbox_predict_var, ":"); - strcat(sandbox_predict_var, "/usr/lib/python2.2/"); - setenv(ENV_SANDBOX_PREDICT, sandbox_predict_var, 1); - /* */ - } - setenv(ENV_SANDBOX_ON, "1", 0); - - /* if the portage temp dir was present, cd into it */ - if (NULL != portage_tmp_dir) - { - chdir(portage_tmp_dir); - } - - /* adding additional bash arguments */ - for (i = 1; i < argc; i++) - { - if (1 == i) - { - argv_bash[3] = run_str; - argv_bash[4] = run_arg; - strcpy(argv_bash[4], argv[i]); - } - else - { - strcat(argv_bash[4], " "); - strcat(argv_bash[4], argv[i]); - } - } - - /* set up the required signal handlers */ - signal(SIGHUP, &stop); - signal(SIGINT, &stop); - signal(SIGQUIT, &stop); - signal(SIGTERM, &stop); - - /* this one should NEVER be set in ebuilds, as it is the one - * private thing libsandbox.so use to test if the sandbox - * should be active for this pid, or not. - * - * azarah (3 Aug 2002) - */ - setenv("SANDBOX_ACTIVE", "armedandready", 1); - - /* fork to executing bash */ - if (argc < 2) - { - printf("Creating a seperate process the run the shell in.\n"); - } - bash_pid = fork(); - - if (0 == bash_pid) - { - /* launch bash */ - execv(argv_bash[0], argv_bash); - } - else - { - int wait_pid = 0; - - if (argc < 2) - { - printf("The protected environment has been started.\n"); - printf("--------------------------------------------------------------------------------\n"); - } - - /* store his sandbox's bash pid in the global pids file if it has rights to adapt the ld.so.preload file*/ - if (1 == preload_adaptable) - { - success = 1; - if (0 == lstat(PIDS_FILE, &pids_stat) && - 0 == S_ISREG(pids_stat.st_mode)) - { - perror(">>> pids file is not a regular file"); - success = 0; - } - else - { - pids_file = open(PIDS_FILE, O_WRONLY|O_CREAT|O_APPEND, 0644); - if (pids_file < 0) - { - perror(">>> pids file open"); - success = 0; - } - else - { - if (flock(pids_file, LOCK_EX) < 0) - { - perror(">>> pids file lock"); - success = 0; - } - else - { - sprintf(pid_string, "%d\n", getpid()); - if (write(pids_file, pid_string, strlen(pid_string)) != strlen(pid_string)) - { - perror(">>> pids file write"); - success = 0; - } - - if (flock(pids_file, LOCK_UN) < 0) - { - perror(">>> pids file unlock"); - success = 0; - } - } - if (close(pids_file) < 0) - { - perror(">>> pids file close"); - success = 0; - } - pids_file = -1; - } - } - if (0 == success) - { - exit(1); - } - } - - /* wait until bash exits */ - wait_pid = waitpid(bash_pid, &status, 0); - } - } - - cleanup(); - - if (argc < 2) - { - printf("========================== Gentoo linux path sandbox ===========================\n"); - printf("The protected environment has been shut down.\n"); - } - if (0 == stat(sandbox_log, &sandbox_log_stat)) - { - sandbox_log_presence = 1; - success = 1; - sandbox_log_file = open(sandbox_log, O_RDONLY, 0); - if (sandbox_log_file < 0) - { - perror(">>> sandbox log file open"); - success = 0; - } - else - { - int i = 0; - char* beep_count_env = NULL; - int beep_count = 0; - int length = 0; - char buffer[255]; - - printf("\e[31;01m--------------------------- ACCESS VIOLATION SUMMARY ---------------------------\033[0m\n"); - printf("\e[31;01mLOG FILE = \"%s\"\033[0m\n", sandbox_log); - printf("\n"); - while ((length = read(sandbox_log_file, buffer, sizeof(buffer)-1)) > 0) - { - if (length < sizeof(buffer)) - { - buffer[length] = 0; - } - printf("%s", buffer); - } - printf("\e[31;01m--------------------------------------------------------------------------------\033[0m\n"); - - if (close(sandbox_log_file) < 0) - { - perror(">>> sandbox log close"); - success = 0; - } - - beep_count_env = getenv(ENV_SANDBOX_BEEP); - if (beep_count_env) - { - beep_count = atoi(beep_count_env); - } - else - { - beep_count = DEFAULT_BEEP_COUNT; - } - for (i = 0; i < beep_count; i++) - { - fputc('\a', stderr); - if (i < beep_count -1) - { - sleep(1); - } - } - - } - if (0 == success) - { - exit(1); - } - sandbox_log_file = -1; - } - else if (argc < 2) - { - printf("--------------------------------------------------------------------------------\n"); - } - - if (status > 0 || - 1 == sandbox_log_presence) - { - return 1; - } - else - { - return 0; - } - } -} |