From: Zac Medico Date: Fri, 27 Jul 2012 02:42:51 +0000 (-0700) Subject: _selinux/spawn_wrapper: setexec *after* fork X-Git-Tag: v2.2.0_alpha121~28 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=d938c3ff0a4ef92451cf6381aeb23a6c2d9ad8f2;p=portage.git _selinux/spawn_wrapper: setexec *after* fork This avoids any interference with concurrent threads in the calling process. --- diff --git a/pym/portage/_selinux.py b/pym/portage/_selinux.py index 9470978c4..173714515 100644 --- a/pym/portage/_selinux.py +++ b/pym/portage/_selinux.py @@ -95,20 +95,32 @@ def setfscreate(ctx="\n"): raise OSError( _("setfscreate: Failed setting fs create context \"%s\".") % ctx) -def spawn_wrapper(spawn_func, selinux_type): - - selinux_type = _unicode_encode(selinux_type, - encoding=_encodings['content'], errors='strict') - - def wrapper_func(*args, **kwargs): - con = settype(selinux_type) - setexec(con) - try: - return spawn_func(*args, **kwargs) - finally: - setexec() - - return wrapper_func +class spawn_wrapper(object): + """ + Create a wrapper function for the given spawn function. When the wrapper + is called, it will adjust the arguments such that setexec() to be called + *after* the fork (thereby avoiding any interference with concurrent + threads in the calling process). + """ + __slots__ = ("_con", "_spawn_func") + + def __init__(self, spawn_func, selinux_type): + self._spawn_func = spawn_func + selinux_type = _unicode_encode(selinux_type, + encoding=_encodings['content'], errors='strict') + self._con = settype(selinux_type) + + def __call__(self, *args, **kwargs): + + pre_exec = kwargs.get("pre_exec") + + def _pre_exec(): + if pre_exec is not None: + pre_exec() + setexec(self._con) + + kwargs["pre_exec"] = _pre_exec + return self._spawn_func(*args, **kwargs) def symlink(target, link, reflnk): target = _unicode_encode(target, encoding=_encodings['fs'], errors='strict')