diff options
author | Chris Houser <chouser@gentoo.org> | 2001-12-19 06:56:52 +0000 |
---|---|---|
committer | Chris Houser <chouser@gentoo.org> | 2001-12-19 06:56:52 +0000 |
commit | 6ef5616f9dfbddb875b86f75bd21635bc04b892c (patch) | |
tree | 05c5b6e3492e80136a1299624afef31701ff774a | |
parent | Added usage docs (diff) | |
download | portage-cvs-6ef5616f9dfbddb875b86f75bd21635bc04b892c.tar.gz portage-cvs-6ef5616f9dfbddb875b86f75bd21635bc04b892c.tar.bz2 portage-cvs-6ef5616f9dfbddb875b86f75bd21635bc04b892c.zip |
add support for running as a non-root user
-rw-r--r-- | man/make.defaults.5 | 94 | ||||
-rw-r--r-- | pym/portage.py | 103 | ||||
-rw-r--r-- | sandbox/dynbash-2.04.ebuild | 46 | ||||
-rw-r--r-- | sandbox/files/digest-dynbash-2.04 | 1 | ||||
-rw-r--r-- | sandbox/files/ebuild.sh.diff | 59 | ||||
-rw-r--r-- | sandbox/files/portage.py.diff | 28 | ||||
-rw-r--r-- | sandbox/files/sandbox/Makefile | 15 | ||||
-rw-r--r-- | sandbox/files/sandbox/libsandbox.c | 776 | ||||
-rw-r--r-- | sandbox/files/sandbox/sandbox.bashrc | 8 | ||||
-rw-r--r-- | sandbox/files/sandbox/sandbox.c | 838 | ||||
-rw-r--r-- | sandbox/sandbox-0.2.2.ebuild | 73 |
11 files changed, 100 insertions, 1941 deletions
diff --git a/man/make.defaults.5 b/man/make.defaults.5 deleted file mode 100644 index 8acebc9..0000000 --- a/man/make.defaults.5 +++ /dev/null @@ -1,94 +0,0 @@ -.TH make.defaults "5" "January 2001" "portage 1.4-r4" -.SH NAME -ebuild \- manual page for make.defaults -.SH SYNOPSIS -.B make.defaults -.SH DESCRIPTION -This File contains various variables that are used by the \fIebuild\fR -script -.PP -.SH VARIABLES -\fBROOT\fR = \fI[path]\fR -This is the default installation target for ebuild. -.TP -\fBMAINTAINER\fR = \fI[yes|no]\fR -If you have and developer cvs access at cvs.gentoo.org -and \fIMAINTAINER\fR is set to \fI"yes"\fR, the md5 checksum files -for the sources get automatically added to the cvs-tree. -.TP -\fBPROXY HTTP_PROXY FTP_PROXY\fR = \fI[host:port]\fR -These vars are used if the sources must be downloaded from the -internet by \fIwget(1)\fR. They are only required if you use a proxy server -for internet access. Eighter define \fIPROXY\fR or -\fIPROXY_FTP\fR and \fIPROXY_HTTP\fR -.TP -\fBGENTOO_MIRRORS\fR = \fI[url]\fR -Insert your nearest \fIIBIBLIO\fR mirror here. This location is tried for -source download before the ones listed in the \fIebuild scripts\fR. -.TP -\fBCHOST\fR -This variable gets passed by the \fIebuild scripts\fR to the \fIconfigure\fR -step as \fI--host=${CHOST}\fR. So you can force the build-host with that. -.TP -\fBMAKEOPTS\fR -Use this variable if you want to use parallel make. -.TP -\fBCFLAGS CXXFLAGS\fR -Use them to controll the optimisation flags of your builds. -.TP -\fBDEBUG\fR -If defined binaries and librarys don't get stripped before \fImerge\fR -.TP -\fBPACKAGE\fR = \fI[tbz2|tgz]\fR -You can define if you want to use gzip(1) or bzip2(1) for package -compression. -.TP -\fBUSE\fR -This variable contains options that controll the build-behaviour of -several packages. More information in ebuild(5). -\fBFETCHCOMMAND\fR -This variable contains the command used for fetching package-sources from -the internet. -.TP -\fBPORTAGE_TMPDIR\fR = \fI[path]\fR -Defines the location of the temporary build directories. -.TP -\fBBUILD_PREFIX\fR = \fI[path]\fR -Defines the location of the package working directory. -.TP -\fBPKG_TMPDIR\fR = \fI[path]\fR -\fIpkgmerge(1)\fR uses this dir to extract the package before the -files get merged to the live filesystem. -.TP -\fBPORTDIR\fR = \fI[path]\fR -Defines the location of all portage dependend subdirs. -.TP -\fBDISTDIR\fR = \fI[path]\fR -Defines the location of the source-files. -.TP -\fBPKGDIR\fR = \fI[path]\fR -Defines the location of the packages. -.TP -\fBRPMDIR\fR = \fI[path]\fR -Defines the location of the RPM packages -.TP -\fBCURRENTILE\fR = \fI[path to file]\fR -Defines the file wich hold a list of all -actuall packages. -.TP -.SH AUTHOR -Achim Gottinger <achim@gentoo.org> -.SH "SEE ALSO" -ebuild(1) ebuild(5) make.conf(5) -.TP -The \fI/usr/sbin/ebuild\fR script. -The helper apps in \fI/usr/lib/portage/bin\fR. -.SH FILES -\fB/etc/make.conf\fR -Contains variables for the build-process and -overwrites those in make.defaults -.TP -\fB/etc/make.defaults\fR -Contains the default variables for the build-process, -you should edit \fI/etc/make.conf\fR instead. -.TP diff --git a/pym/portage.py b/pym/portage.py index 3f4adde..09725e0 100644 --- a/pym/portage.py +++ b/pym/portage.py @@ -68,6 +68,7 @@ #will not be considered for this dependency. import string,os +import re from stat import * from commands import * import fchksum,types @@ -540,11 +541,75 @@ class config: for x in self.keys(): mydict[x]=self[x] return mydict + +class privclass: + """One-off object for handling the current process's real and effective + uid. Instantiated by this module as 'portage.privs'""" + def __init__(self): + self.intercept = "/usr/lib/portage/lib/intercept.so" + self.psre = re.compile("(\d+)\s+(\d+)") + self.target = None # uid to use during unsafe operations + self.old = os.getuid() # original uid when run (often root) + self.debug = os.getenv("DEBUG_PORTAGE") + + def stayroot(self, root): + """Applies user's 'stayroot' preference. Must be run before any drop or + recover operation.""" + if root: + self.target = os.getuid() + else: + self.target = self.gettarget() + self.drop() + + def gettarget(self): + """Walk up through process ancestry looking for a non-root uid""" + uid = self.old + pid = os.getppid() + while uid == 0 and pid > 1: + cmd = "ps --noheaders -o uid,ppid %d" % pid + uid, pid = self.psre.search(os.popen(cmd).read()).groups() + uid, pid = int(uid), int(pid) + # if no non-root uid is found, use 'portage' uid 35 + if uid == 0: + print "!!! no non-root user in process tree: using uid 35 (portage)" + uid = 35 + return uid -def spawn(mystring,debug=0): + def drop(self): + """Drop root privs by setting euid to target uid""" + if os.geteuid() != self.target: + os.seteuid(self.target) + if self.debug: print "!!! Drop root privs (uid %d)" % self.target + + def recover(self): + """Recover root privs by setting euid to root uid (0)""" + if os.getuid() == 0: + os.seteuid(0) + if self.debug: print "!!! Recover root privs" + + def dropall(self, msg=''): + """Drop root privs by setting euid and real uid to target uid. + After this, root privs cannot be recovered by this process.""" + # if we're not root, we've got no privs to drop + if os.getuid() != self.target: + os.seteuid(0) + os.setuid(self.target) + os.seteuid(self.target) + if self.debug: print "!!! Drop ALL root privs (uid %d)" %self.target + # set up LD_PRELOAD to intercept system calls that would be illegal + if os.getuid() != 0: + settings["LD_PRELOAD"] = self.intercept + # next is an ugly hack to get around make unsetting LD_PRELOAD + settings["MAKEFLAGS"] = "LD_PRELOAD=" + self.intercept + if self.debug: print "!!! Load intercept " + msg + +def spawn(mystring,debug=0,stayroot=0): global settings mypid=os.fork() if mypid==0: + # drop all root privs for this forked process + if not stayroot: + privs.dropall(mystring) mycommand="/bin/bash" if debug: myargs["bash","-x","-c",mystring] @@ -609,7 +674,8 @@ def doebuild(myebuild,mydo,myroot,checkdeps=1,debug=0): os.makedirs(settings["T"]) settings["WORKDIR"]=settings["BUILDDIR"]+"/work" settings["D"]=settings["BUILDDIR"]+"/image/" - + settings["AUTOSCRIPT"]=settings["BUILDDIR"]+"/build-info/AUTOSCRIPT" + #initial ebuild.sh bash environment configured myso=getstatusoutput("/usr/sbin/ebuild.sh depend") if myso[0]!=0: @@ -655,6 +721,10 @@ def doebuild(myebuild,mydo,myroot,checkdeps=1,debug=0): a=open(settings["T"]+"/src_uri_all","w") a.write(flatten(alluris)) a.close() + + # clear out old AUTOSCRIPT before doing an install + if (mydo=="install" or mydo=="merge") and os.path.isfile(settings["AUTOSCRIPT"]): + os.unlink(settings["AUTOSCRIPT"]) if mydo=="unpack": return spawn("/usr/sbin/ebuild.sh fetch unpack") @@ -662,12 +732,20 @@ def doebuild(myebuild,mydo,myroot,checkdeps=1,debug=0): return spawn("/usr/sbin/ebuild.sh fetch unpack compile") elif mydo=="install": return spawn("/usr/sbin/ebuild.sh fetch unpack compile install") - elif mydo in ["prerm","postrm","preinst","postinst","config","touch","clean","fetch","digest","batchdigest"]: + elif mydo in ["config","touch","clean","fetch","digest","batchdigest"]: return spawn("/usr/sbin/ebuild.sh "+mydo) + elif mydo in ["prerm","postrm","preinst","postinst"]: + if os.getuid() != 0: + print "!!! The '%s' step must be done as root" % mydo + return -1 + return spawn("/usr/sbin/ebuild.sh "+mydo, stayroot=1) elif mydo=="qmerge": #qmerge is specifically not supposed to do a runtime dep check return merge(settings["CATEGORY"],settings["PF"],settings["D"],settings["BUILDDIR"]+"/build-info",myroot) elif mydo=="merge": + if os.getuid() != 0: + print "!!! The 'merge' step must be done as root" + return -1 retval=spawn("/usr/sbin/ebuild.sh fetch unpack compile install") if retval: return retval if checkdeps: @@ -771,17 +849,21 @@ def pathstrip(x,mystart): return [root+x[len(cpref)+1:],x[len(cpref):]] def merge(mycat,mypkg,pkgloc,infloc,myroot): + privs.recover() # pick up root privs needed for merge mylink=dblink(mycat,mypkg,myroot) if not mylink.exists(): mylink.create() #shell error code mylink.merge(pkgloc,infloc,myroot) + privs.drop() # done with root privs def unmerge(cat,pkg,myroot): + privs.recover() # pick up root privs needed for unmerge mylink=dblink(cat,pkg,myroot) if mylink.exists(): mylink.unmerge() mylink.delete() + privs.drop() # done with root privs def getenv(mykey,dictlist=[]): "dictlist contains a list of dictionaries to check *before* the environment" @@ -2051,6 +2133,14 @@ class dblink: self.create() #open contents file if it isn't already open mergestart=mergeroot + #make sure all files are owned by root. + print ">>> Chown work dir to root..." + os.system("chown -R 0:0 "+mergeroot) + #now adjust ownership as recorded during 'install' + if os.path.isfile(settings["AUTOSCRIPT"]): + print ">>> Executing AUTOSCRIPT..." + os.chmod(settings["AUTOSCRIPT"], 0744) + spawn(settings["AUTOSCRIPT"]) print ">>> Updating mtimes..." #before merging, it's *very important* to touch all the files !!! os.system("(cd "+mergeroot+"; for x in `find`; do touch -c $x 2>/dev/null; done)") @@ -2252,6 +2342,9 @@ class dblink: os.umask(prevmask) #if we opened it, close it outfile.close() + print ">>> Chown work dir to non-root..." + #make sure all files are owned so they can be cleaned by non-root later + os.system("chown -R %d %s" % (privs.target, mergeroot)) if (oldcontents): print ">>> Safely unmerging already-installed instance..." self.unmerge(oldcontents) @@ -2401,6 +2494,7 @@ def pkgmerge(mytbz2,myroot): xptbz2.unpackinfo(infloc) origdir=os.getcwd() os.chdir(pkgloc) + privs.recover() # pick up root privs needed for pkgmerge print ">>> extracting",mypkg notok=os.system("cat "+mytbz2+"| bzip2 -dq | tar xpf -") if notok: @@ -2421,6 +2515,7 @@ def pkgmerge(mytbz2,myroot): returnme=string.join(string.split(a.read())," ") a.close() cleanup_pkgmerge(mypkg,origdir) + privs.drop() # done with root privs return returnme def ebuild_init(): "performs db/variable initialization for the ebuild system. Not required for other scripts." @@ -2473,3 +2568,5 @@ if root!="/": if not profiledir: if os.path.exists("/etc/make.profile/make.defaults"): profiledir="/etc/make.profile" +# init the shared privs object +privs = privclass() diff --git a/sandbox/dynbash-2.04.ebuild b/sandbox/dynbash-2.04.ebuild deleted file mode 100644 index 2dd6457..0000000 --- a/sandbox/dynbash-2.04.ebuild +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 1999-2001 Gentoo Technologies, Inc. -# Distributed under the terms of the GNU General Public License, v2 or later -# Author: Geert Bevin <gbevin@theleaf.be> -# $ Header: $ - -S=${WORKDIR}/bash-${PV} -DESCRIPTION="The standard GNU Bourne again shell" -SRC_URI="ftp://ftp.gnu.org/gnu/bash/bash-${PV}.tar.gz" - -HOMEPAGE="http://www.gnu.org/software/bash/bash.html" - -DEPEND=">=sys-libs/ncurses-5.2-r2 - readline? ( >=sys-libs/readline-4.1-r2 )" - -RDEPEND="virtual/glibc" - -src_compile() { - - local myconf - [ "`use readline`" ] && myconf="--with-installed-readline" - [ -z "`use nls`" ] && myconf="${myconf} --disable-nls" - ./configure --prefix=/ --mandir=/usr/share/man --infodir=/usr/share/info --host=${CHOST} --disable-profiling --with-curses --without-gnu-malloc ${myconf} || die - emake || die - -} - -src_install() { - - dodir /bin - cp -af /bin/bash ${D}/bin/sbash - cp ${S}/bash ${D}/bin - -} - -pkg_prerm() { - - mv /bin/bash /bin/dbash - cp -af /bin/sbash /bin/bash - -} - -pkg_postrm() { - - rm /bin/dbash - -} diff --git a/sandbox/files/digest-dynbash-2.04 b/sandbox/files/digest-dynbash-2.04 deleted file mode 100644 index 81a4c0a..0000000 --- a/sandbox/files/digest-dynbash-2.04 +++ /dev/null @@ -1 +0,0 @@ -MD5 49b548a8b72a4c925ff26930e4c31c6c bash-2.04.tar.gz 1712128 diff --git a/sandbox/files/ebuild.sh.diff b/sandbox/files/ebuild.sh.diff deleted file mode 100644 index d674ffe..0000000 --- a/sandbox/files/ebuild.sh.diff +++ /dev/null @@ -1,59 +0,0 @@ ---- ebuild.sh.orig Mon Dec 10 11:56:04 2001 -+++ ebuild.sh Mon Dec 10 12:01:54 2001 -@@ -1,4 +1,29 @@ - #!/bin/bash -+ -+# disable the sandbox for now ... -+export SANDBOX_ON="0" -+ -+# sandbox support functions -+addread() -+{ -+ export SANDBOX_READ="$SANDBOX_READ:$1" -+} -+ -+addwrite() -+{ -+ export SANDBOX_WRITE="$SANDBOX_WRITE:$1" -+} -+ -+adddeny() -+{ -+ export SANDBOX_DENY="$SANDBOX_DENY:$1" -+} -+ -+addpredict() -+{ -+ export SANDBOX_PREDICT="$SANDBOX_PREDICT:$1" -+} -+ - #we need this next line for "die" and "assert" - shopt -s expand_aliases - source /etc/profile.env > /dev/null 2>&1 -@@ -694,7 +719,25 @@ - set +x - fi - ;; -- unpack|compile|help|touch|clean|fetch|digest|pkginfo|pkgloc|unmerge|merge|package|install|rpm) -+ # Only enable the SandBox for these functions -+ unpack|compile|clean|install) -+ if [ ${SANDBOX_DISABLED="0"} = "0" ] -+ then -+ export SANDBOX_ON="1" -+ else -+ export SANDBOX_ON="0" -+ fi -+ if [ "$PORTAGE_DEBUG" = "0" ] -+ then -+ dyn_${myarg} -+ else -+ set -x -+ dyn_${myarg} -+ set +x -+ fi -+ export SANDBOX_ON="0" -+ ;; -+ help|touch|fetch|digest|pkginfo|pkgloc|unmerge|merge|package|rpm) - if [ "$PORTAGE_DEBUG" = "0" ] - then - dyn_${myarg} diff --git a/sandbox/files/portage.py.diff b/sandbox/files/portage.py.diff deleted file mode 100644 index 13f78f4..0000000 --- a/sandbox/files/portage.py.diff +++ /dev/null @@ -1,28 +0,0 @@ ---- portage.py.orig Thu Dec 6 22:24:34 2001 -+++ portage.py Thu Dec 6 23:10:11 2001 -@@ -525,11 +525,14 @@ - global settings - mypid=os.fork() - if mypid==0: -- mycommand="/bin/bash" -+# mycommand="/bin/bash" -+ mycommand="/usr/bin/sandbox" - if debug: -- myargs["bash","-x","-c",mystring] -+# myargs["bash","-x","-c",mystring] -+ myargs=["sandbox",mystring] - else: -- myargs=["bash","-c",mystring] -+# myargs["bash","-c",mystring] -+ myargs=["sandbox",mystring] - os.execve(mycommand,myargs,settings.environ()) - return - retval=os.waitpid(mypid,0)[1] -@@ -559,6 +562,7 @@ - #PEBUILD - settings["FILESDIR"]=settings["O"]+"/files" - settings["PF"]=os.path.basename(settings["EBUILD"])[:-7] -+ settings["SANDBOX_LOG"]=settings["PF"] - mysplit=pkgsplit(settings["PF"],0) - if mysplit==None: - print "!!! Error: PF is null; exiting." diff --git a/sandbox/files/sandbox/Makefile b/sandbox/files/sandbox/Makefile deleted file mode 100644 index 75a1e4c..0000000 --- a/sandbox/files/sandbox/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (C) 2001 The Leaf, http://www.theleaf.be -# Distributed under the terms of the GNU General Public License, v2 or later -# Author : Geert Bevin <gbevin@theleaf.be> -# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/sandbox/files/sandbox/Attic/Makefile,v 1.2 2001/12/06 22:26:33 gbevin Exp $ -default: sandbox libsandbox.so - -sandbox: sandbox.c - gcc -Wall -O2 -o sandbox sandbox.c - -libsandbox.so: libsandbox.c - gcc -Wall -O2 -ldl --shared -o libsandbox.so libsandbox.c - -clean: - rm sandbox - rm libsandbox.so diff --git a/sandbox/files/sandbox/libsandbox.c b/sandbox/files/sandbox/libsandbox.c deleted file mode 100644 index 96de35c..0000000 --- a/sandbox/files/sandbox/libsandbox.c +++ /dev/null @@ -1,776 +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 The Leaf, http://www.theleaf.be -** Distributed under the terms of the GNU General Public License, v2 or later -** Author : Geert Bevin <gbevin@theleaf.be> -** $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/sandbox/files/sandbox/Attic/libsandbox.c,v 1.7 2001/12/11 19:02:13 gbevin 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; - -void init_context(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*); -void init_env_entries(char***, int*, char*); -int is_sandbox_pid(); -void* get_dl_symbol(char*); - -/* 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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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]; - - init_env_entries(&path_entries, &num_path_entries, "PATH"); - 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 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) -{ - 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)++] = 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)++] = prefix; - } - } -} - -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; -} - -int check_access(sbcontext_t* sbcontext, const char* func, const char* path) -{ - int i = 0; - char* filtered_path = (char*)path; - - if ('/' != path[0]) - { - return 0; - } - while ('/' == *filtered_path) - { - filtered_path++; - } - filtered_path--; - - if (0 == strcmp(filtered_path, "/etc/ld.so.preload") && - is_sandbox_pid()) - { - return 1; - } - - 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]))) - { - return 0; - } - } - } - - 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]))) - { - return 1; - } - } - } - 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]))) - { - return 0; - } - } - for (i = 0; i < sbcontext->num_write_prefixes; i++) - { - if (0 == strncmp(filtered_path, sbcontext->write_prefixes[i], strlen(sbcontext->write_prefixes[i]))) - { - return 1; - } - } - - /* 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; - return 0; - } - } - - 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; - return 0; - } - } - - } - - - return 0; -} - -int check_syscall(sbcontext_t* sbcontext, const char* func, const char* file) -{ - int result = 1; - char* absolute_path = NULL; - char* tmp_buffer = NULL; - char* log_path = NULL; - int log_file = 0; - 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); - 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); - 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 before_syscall(const char* func, const char* file) -{ - int result = 1; - - sbcontext_t sbcontext; - - init_context(&sbcontext); - - if (NULL != getenv("SANDBOX_ON") && - 0 == strcmp(getenv("SANDBOX_ON"), "1")) - { - init_env_entries(&(sbcontext.deny_prefixes), &(sbcontext.num_deny_prefixes), "SANDBOX_DENY"); - init_env_entries(&(sbcontext.read_prefixes), &(sbcontext.num_read_prefixes), "SANDBOX_READ"); - init_env_entries(&(sbcontext.write_prefixes), &(sbcontext.num_write_prefixes), "SANDBOX_WRITE"); - init_env_entries(&(sbcontext.predict_prefixes), &(sbcontext.num_predict_prefixes), "SANDBOX_PREDICT"); - - 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_RDONLY) - { - return before_syscall("open_rd", file); - } - else - { - return before_syscall("open_wr", 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/sandbox/files/sandbox/sandbox.bashrc b/sandbox/files/sandbox/sandbox.bashrc deleted file mode 100644 index c767845..0000000 --- a/sandbox/files/sandbox/sandbox.bashrc +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) 2001 The Leaf, http://www.theleaf.be -# Distributed under the terms of the GNU General Public License, v2 or later -# Author : Geert Bevin <gbevin@theleaf.be> -# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/sandbox/files/sandbox/Attic/sandbox.bashrc,v 1.2 2001/12/06 22:26:33 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/sandbox/files/sandbox/sandbox.c b/sandbox/files/sandbox/sandbox.c deleted file mode 100644 index 7022044..0000000 --- a/sandbox/files/sandbox/sandbox.c +++ /dev/null @@ -1,838 +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 The Leaf, http://www.theleaf.be -** Distributed under the terms of the GNU General Public License, v2 or later -** Author : Geert Bevin <gbevin@theleaf.be> -** $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/sandbox/files/sandbox/Attic/sandbox.c,v 1.9 2001/12/13 20:33:42 gbevin Exp $ -*/ - -#define _GNU_SOURCE - -#include <errno.h> -#include <fcntl.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.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; - 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; - 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 = NULL; - 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; - - 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, "/usr/lib/sandbox/"); - 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/sandbox/"); - 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; - 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"); - portage_tmp_dir = getenv("PORTAGE_TMPDIR"); - 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/null:/dev/pts/:/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"); - } - else - { - strcat(sandbox_write_var, portage_tmp_dir); - } - /* */ - 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, "/."); - 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); - - /* 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; - 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; - } - } -} diff --git a/sandbox/sandbox-0.2.2.ebuild b/sandbox/sandbox-0.2.2.ebuild deleted file mode 100644 index db34dbf..0000000 --- a/sandbox/sandbox-0.2.2.ebuild +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright 1999-2000 Gentoo Technologies, Inc. -# Distributed under the terms of the GNU General Public License, v2 or later -# Author: Martin Schlemmer <azarah@gentoo.org> -# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/sandbox/Attic/sandbox-0.2.2.ebuild,v 1.1 2001/12/11 22:21:09 gbevin Exp $ - -S=${WORKDIR}/sandbox -DESCRIPTION="Portage SandBox System" -SRC_URI="" -HOMEPAGE="" - -DEPEND="virtual/glibc - =sys-apps/portage-1.7.4" - - -src_unpack() { - - mkdir -p ${S} - cd ${S} - cp ${FILESDIR}/sandbox/*sandbox* . || die - cp ${FILESDIR}/sandbox/Makefile . || die - -} - -src_compile() { - - cp /usr/lib/portage/pym/portage.py . - cp portage.py portage.py.orig - cp /usr/lib/portage/bin/ebuild.sh . - cp ebuild.sh ebuild.sh.orig - - patch <${FILESDIR}/portage.py.diff || die - patch <${FILESDIR}/ebuild.sh.diff || die - - emake || die -} - -src_install() { - - dodir /usr/bin /usr/lib/sandbox - dodir /usr/lib/portage/{bin,pym} - - into /usr - dobin sandbox - exeinto /usr/lib/sandbox - doexe libsandbox.so - insinto /usr/lib/sandbox - doins sandbox.bashrc - insinto /usr/lib/portage/pym - doins portage.py portage.py.orig - exeinto /usr/lib/portage/bin - doexe ebuild.sh ebuild.sh.orig -} - -pkg_prerm() { - - # Restore the original portage files - cp -f /usr/lib/portage/pym/portage.py.orig /usr/lib/portage/pym/portage.py - cp -f /usr/lib/portage/bin/ebuild.sh.orig /usr/lib/portage/bin/ebuild.sh - # Make the current ebuild use bash instead of sandbox further on - rm -f /usr/bin/sandbox - echo '#!/bin/bash' > /usr/bin/sandbox - echo '/bin/bash -c "$@"' >> /usr/bin/sandbox - chmod 755 /usr/bin/sandbox - -} - -pkg_postrm() { - - # Remove the temporary sandbox script - rm -f /usr/bin/sandbox - -} - |