summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael E Brown <mebrown@michaels-house.net>2007-10-18 21:39:52 -0500
committerMichael E Brown <mebrown@michaels-house.net>2007-10-18 21:39:52 -0500
commit9e820575ac528d562fc9bd207c8674bfed03589d (patch)
treeb8167af16e4527861c411f10bed5c2837c98940c /src
parenta9172fdfdf9811cb84626f0a414668cc2ab03dc4 (diff)
downloadmock-9e820575ac528d562fc9bd207c8674bfed03589d.tar.gz
mock-9e820575ac528d562fc9bd207c8674bfed03589d.tar.xz
mock-9e820575ac528d562fc9bd207c8674bfed03589d.zip
completely drop privs (real and effective) when running RPM commands. add a bit of infrastructure to mock.util.do() to handle this. Change mock.util.do to not return output by default. No users use the output, and it can be switched on via karg.
Diffstat (limited to 'src')
-rw-r--r--src/py-libs/backend.py48
-rw-r--r--src/py-libs/util.py33
2 files changed, 44 insertions, 37 deletions
diff --git a/src/py-libs/backend.py b/src/py-libs/backend.py
index 6a190fa..809383d 100644
--- a/src/py-libs/backend.py
+++ b/src/py-libs/backend.py
@@ -210,6 +210,7 @@ class Root(object):
# files in /dev
mock.util.rmtree(os.path.join(self.rootdir, "dev"))
mock.util.mkdirIfAbsent(os.path.join(self.rootdir, "dev", "pts"))
+ prevMask = os.umask(0000)
os.mknod(os.path.join(self.rootdir, "dev/zero"), stat.S_IFCHR | 0666, os.makedev(1, 5))
os.mknod(os.path.join(self.rootdir, "dev/tty"), stat.S_IFCHR | 0666, os.makedev(5, 0))
os.mknod(os.path.join(self.rootdir, "dev/null"), stat.S_IFCHR | 0666, os.makedev(1, 3))
@@ -219,6 +220,7 @@ class Root(object):
os.symlink("/proc/self/fd/0", os.path.join(self.rootdir, "dev/stdin"))
os.symlink("/proc/self/fd/1", os.path.join(self.rootdir, "dev/stdout"))
os.symlink("/proc/self/fd/2", os.path.join(self.rootdir, "dev/stderr"))
+ os.umask(prevMask)
# set up cache dirs:
self._initCache()
@@ -292,8 +294,13 @@ class Root(object):
srpmBasename = os.path.basename(srpmChrootFilename)
# install srpm
- env = "HOME=%s" % self.homedir
- self.doChroot("rpm -Uvh --nodeps %s" % srpmChrootFilename, env=env)
+ os.environ["HOME"] = self.homedir
+ # Completely/Permanently drop privs while running the following:
+ mock.util.do(
+ "rpm -Uvh --nodeps %s" % srpmChrootFilename,
+ chrootPath=self.rootdir,
+ uidManager=self.uidManager,
+ )
# rebuild srpm/rpm from SPEC file
specs = glob.glob("%s/%s/SPECS/*.spec" % (self.rootdir, self.builddir))
@@ -302,9 +309,13 @@ class Root(object):
spec = specs[0] # if there's more than one then someone is an idiot
chrootspec = spec.replace(self.rootdir, '') # get rid of rootdir prefix
- self.doChroot(
+ self.root_log.info("about to drop to unpriv mode.")
+ # Completely/Permanently drop privs while running the following:
+ mock.util.do(
"rpmbuild -bs --target %s --nodeps %s" % (self.target_arch, chrootspec),
- env=env, logger=self.build_log, timeout=timeout, output=0
+ chrootPath=self.rootdir,
+ uidManager=self.uidManager,
+ logger=self.build_log, timeout=timeout,
)
rebuiltSrpmFile = glob.glob("%s/%s/SRPMS/*.src.rpm" % (self.rootdir, self.builddir))
@@ -315,28 +326,13 @@ class Root(object):
self.installSrpmDeps(rebuiltSrpmFile)
#have to permanently drop privs or rpmbuild regains them
- # can only do this by forking...
self.state("build")
- pid = os.fork()
- if pid:
- # parent
- try:
- os.waitpid(pid,0)
- except:
- os.kill(-pid, signal.SIGTERM)
- time.sleep(1)
- os.kill(-pid, signal.SIGKILL)
-
- else:
- # child
- try:
- uidManager.dropPrivsForever()
- self.doChroot(
- "rpmbuild -bb --target %s --nodeps %s" % (self.target_arch, chrootspec),
- env=env, logger=self.build_log, timeout=timeout, output=0
- )
- finally:
- os._exit(0)
+ mock.util.do(
+ "rpmbuild -bb --target %s --nodeps %s" % (self.target_arch, chrootspec),
+ chrootPath=self.rootdir,
+ uidManager=self.uidManager,
+ logger=self.build_log, timeout=timeout,
+ )
bd_out = self.rootdir + self.builddir
rpms = glob.glob(bd_out + '/RPMS/*.rpm')
@@ -495,7 +491,7 @@ class Root(object):
self.root_log.info(cmd)
try:
self._callHooks("preyum")
- mock.util.do(cmd, output=0)
+ mock.util.do(cmd)
self._callHooks("postyum")
except mock.exception.Error, e:
self.root_log.exception("Error performing yum command: %s" % cmd)
diff --git a/src/py-libs/util.py b/src/py-libs/util.py
index 0bca233..868fb41 100644
--- a/src/py-libs/util.py
+++ b/src/py-libs/util.py
@@ -142,24 +142,19 @@ def uniqReqs(*args):
master.extend(l)
return rpmUtils.miscutils.unique(master)
-@traceLog(log)
-def do_interactive(command, *args, **kargs):
- # we always assume that we dont care about return code for interactive stuff
- os.system(command)
-
# logger =
# output = [1|0]
+# chrootPath
+#
+# Warning: this is the function from hell. :(
+#
@traceLog(log)
-def do(command, timeout=0, raiseExc=True, interactive=0, *args, **kargs):
+def do(command, chrootPath=None, timeout=0, raiseExc=True, returnOutput=0, *args, **kargs):
"""execute given command outside of chroot"""
logger = kargs.get("logger", log)
logger.debug("Run cmd: %s" % command)
- # need to not fork, etc or interactive command wont properly display, so catch it here.
- if interactive:
- return do_interactive(command, timeout=timeout, raiseExc=raiseExc, *args, **kargs)
-
class alarmExc(Exception): pass
def alarmhandler(signum,stackframe):
raise alarmExc("timeout expired")
@@ -187,7 +182,7 @@ def do(command, timeout=0, raiseExc=True, interactive=0, *args, **kargs):
else:
logger.debug(line)
- if kargs.get("output",1):
+ if returnOutput:
output += line
# close read handle, get child return status, etc
@@ -225,6 +220,22 @@ def do(command, timeout=0, raiseExc=True, interactive=0, *args, **kargs):
# can kill our children
os.setpgrp()
+ uidManager = kargs.get("uidManager")
+
+ if chrootPath is not None:
+ if uidManager:
+ logger.debug("elevate privs to run chroot")
+ uidManager.becomeUser(0)
+ os.chdir(chrootPath)
+ os.chroot(chrootPath)
+ if uidManager:
+ logger.debug("back to other privs")
+ uidManager.restorePrivs()
+
+ if uidManager:
+ logger.debug("about to drop privs")
+ uidManager.dropPrivsForever()
+
child = popen2.Popen4(command)
child.tochild.close()