From cb73599de0449898170f11dc22e041d62367bffc Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Thu, 17 May 2018 20:57:59 -0700 Subject: [PATCH] preinst_selinux_labels: disable LD_PRELOAD sandbox (bug 655996) Since SELinux does not allow LD_PRELOAD across domain transitions, disable the LD_PRELOAD sandbox for preinst_selinux_labels. Bug: https://bugs.gentoo.org/655996 --- pym/_emerge/EbuildPhase.py | 30 +++++++++++++++++++++++++++++- pym/_emerge/MiscFunctionsProcess.py | 6 +++++- pym/portage/package/ebuild/doebuild.py | 28 +++++++++++++++++++++------- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/pym/_emerge/EbuildPhase.py b/pym/_emerge/EbuildPhase.py index 890b178702..d057dc45e3 100644 --- a/pym/_emerge/EbuildPhase.py +++ b/pym/_emerge/EbuildPhase.py @@ -13,6 +13,7 @@ from _emerge.MiscFunctionsProcess import MiscFunctionsProcess from _emerge.EbuildProcess import EbuildProcess from _emerge.CompositeTask import CompositeTask from _emerge.PackagePhase import PackagePhase +from _emerge.TaskSequence import TaskSequence from portage.package.ebuild.prepare_build_dirs import (_prepare_workdir, _prepare_fake_distdir, _prepare_fake_filesdir) from portage.util import writemsg @@ -275,7 +276,7 @@ class EbuildPhase(CompositeTask): # when FEATURES=compress-build-logs is enabled. fd, logfile = tempfile.mkstemp() os.close(fd) - post_phase = MiscFunctionsProcess(background=self.background, + post_phase = _PostPhaseCommands(background=self.background, commands=post_phase_cmds, fd_pipes=self.fd_pipes, logfile=logfile, phase=self.phase, scheduler=self.scheduler, settings=settings) @@ -405,3 +406,30 @@ class EbuildPhase(CompositeTask): log_path = self.settings.get("PORTAGE_LOG_FILE") self.scheduler.output(msg, log_path=log_path, background=background) + + +class _PostPhaseCommands(CompositeTask): + + __slots__ = ("commands", "fd_pipes", "logfile", "phase", "settings") + + def _start(self): + if isinstance(self.commands, list): + cmds = [({}, self.commands)] + else: + cmds = list(self.commands) + + if 'selinux' not in self.settings.features: + cmds = [(kwargs, commands) for kwargs, commands in + cmds if not kwargs.get('selinux_only')] + + tasks = TaskSequence() + for kwargs, commands in cmds: + # Select args intended for MiscFunctionsProcess. + kwargs = dict((k, v) for k, v in kwargs.items() + if k in ('ld_preload_sandbox',)) + tasks.add(MiscFunctionsProcess(background=self.background, + commands=commands, fd_pipes=self.fd_pipes, + logfile=self.logfile, phase=self.phase, + scheduler=self.scheduler, settings=self.settings, **kwargs)) + + self._start_task(tasks, self._default_final_exit) diff --git a/pym/_emerge/MiscFunctionsProcess.py b/pym/_emerge/MiscFunctionsProcess.py index 99cf5983f7..89fd226351 100644 --- a/pym/_emerge/MiscFunctionsProcess.py +++ b/pym/_emerge/MiscFunctionsProcess.py @@ -13,7 +13,7 @@ class MiscFunctionsProcess(AbstractEbuildProcess): Spawns misc-functions.sh with an existing ebuild environment. """ - __slots__ = ('commands',) + __slots__ = ('commands', 'ld_preload_sandbox') def _start(self): settings = self.settings @@ -29,6 +29,10 @@ class MiscFunctionsProcess(AbstractEbuildProcess): AbstractEbuildProcess._start(self) def _spawn(self, args, **kwargs): + # If self.ld_preload_sandbox is None, default to free=False, + # in alignment with the spawn(free=False) default. + kwargs.setdefault('free', False if self.ld_preload_sandbox is None + else not self.ld_preload_sandbox) if self._dummy_pipe_fd is not None: self.settings["PORTAGE_PIPE_FD"] = str(self._dummy_pipe_fd) diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py index 31b552ff36..c3b89ade23 100644 --- a/pym/portage/package/ebuild/doebuild.py +++ b/pym/portage/package/ebuild/doebuild.py @@ -1722,13 +1722,27 @@ _post_phase_cmds = { "install_symlink_html_docs", "install_hooks"], - "preinst" : [ - "preinst_sfperms", - "preinst_selinux_labels", - "preinst_suid_scan", - "preinst_qa_check", - ], - + "preinst" : ( + ( + # Since SELinux does not allow LD_PRELOAD across domain transitions, + # disable the LD_PRELOAD sandbox for preinst_selinux_labels. + { + "ld_preload_sandbox": False, + "selinux_only": True, + }, + [ + "preinst_selinux_labels", + ], + ), + ( + {}, + [ + "preinst_sfperms", + "preinst_suid_scan", + "preinst_qa_check", + ], + ), + ), "postinst" : [ "postinst_qa_check"], } -- 2.13.6