summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2007-01-17 23:01:09 +0000
committerZac Medico <zmedico@gentoo.org>2007-01-17 23:01:09 +0000
commitc25d86eb4ee0e2214e71259bca4998a67ce7c227 (patch)
tree43cfb9ba6db2381c4fb8955d2df731a0fc180a06
parentUse the portable -o option for tar. Thanks to Timothy Redaelli <drizzt@gento... (diff)
downloadportage-multirepo-c25d86eb4ee0e2214e71259bca4998a67ce7c227.tar.gz
portage-multirepo-c25d86eb4ee0e2214e71259bca4998a67ce7c227.tar.bz2
portage-multirepo-c25d86eb4ee0e2214e71259bca4998a67ce7c227.zip
For bug #162404, spawn tee outside the sesandbox domain so that it reads from a pipe between two domains. (trunk r5689:5691)
svn path=/main/branches/2.1.2/; revision=5692
-rw-r--r--pym/portage.py56
1 files changed, 50 insertions, 6 deletions
diff --git a/pym/portage.py b/pym/portage.py
index 13014ef6..53eac070 100644
--- a/pym/portage.py
+++ b/pym/portage.py
@@ -2164,6 +2164,29 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keyw
env=mysettings.environ()
keywords["opt_name"]="[%s]" % mysettings["PF"]
+ # The default policy for the sesandbox domain only allows entry (via exec)
+ # from shells and from binaries that belong to portage (the number of entry
+ # points is minimized). The "tee" binary is not among the allowed entry
+ # points, so it is spawned outside of the sesandbox domain and reads from a
+ # pipe between two domains.
+ logfile = keywords.get("logfile")
+ mypids = []
+ pw = None
+ if logfile:
+ del keywords["logfile"]
+ fd_pipes = keywords.get("fd_pipes")
+ if fd_pipes is None:
+ fd_pipes = {0:0, 1:1, 2:2}
+ elif 1 not in fd_pipes or 2 not in fd_pipes:
+ raise ValueError(fd_pipes)
+ pr, pw = os.pipe()
+ mypids.extend(portage_exec.spawn(('tee', '-i', '-a', logfile),
+ returnpid=True, fd_pipes={0:pr, 1:fd_pipes[1], 2:fd_pipes[2]}))
+ os.close(pr)
+ fd_pipes[1] = pw
+ fd_pipes[2] = pw
+ keywords["fd_pipes"] = fd_pipes
+
features = mysettings.features
# XXX: Negative RESTRICT word
droppriv=(droppriv and ("userpriv" in features) and not \
@@ -2189,12 +2212,33 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keyw
con = con.replace(mysettings["PORTAGE_T"], mysettings["PORTAGE_SANDBOX_T"])
selinux.setexec(con)
- retval = spawn_func(mystring, env=env, **keywords)
-
- if sesandbox:
- selinux.setexec(None)
-
- return retval
+ returnpid = keywords.get("returnpid")
+ keywords["returnpid"] = True
+ try:
+ mypids.extend(spawn_func(mystring, env=env, **keywords))
+ finally:
+ if pw:
+ os.close(pw)
+ if sesandbox:
+ selinux.setexec(None)
+
+ if returnpid:
+ return mypids
+
+ while mypids:
+ pid = mypids.pop(0)
+ retval = os.waitpid(pid, 0)[1]
+ portage_exec.spawned_pids.remove(pid)
+ if retval != os.EX_OK:
+ for pid in mypids:
+ if os.waitpid(pid, os.WNOHANG) == (0,0):
+ os.kill(pid, signal.SIGTERM)
+ os.waitpid(pid, 0)
+ portage_exec.spawned_pids.remove(pid)
+ if retval & 0xff:
+ return (retval & 0xff) << 8
+ return retval >> 8
+ return os.EX_OK
def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",use_locks=1, try_mirrors=1):
"fetch files. Will use digest file if available."