commit:     5c46a42710067d2605ceb00df795d8879feb0471
Author:     Jason Zaman <perfinion <AT> gentoo <DOT> org>
AuthorDate: Mon Aug 29 01:25:05 2016 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Thu Sep 15 19:56:07 2016 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=5c46a427

selinux: fix crash for invalid context

When selinux is not fully installed yet the getcon call can sometimes return
"kernel" instead of a correct triple (eg "root:sysadm_r:sysadm_t"). Catch the
IndexError and skip selinux initialization.

Traceback (most recent call last):
  File "/usr/lib64/python2.7/site-packages/portage/util/_async/ForkProcess.py", 
line 45, in _spawn
    rval = self._run()
  File "/usr/lib64/python2.7/site-packages/_emerge/EbuildFetcher.py", line 172, 
in _run
    allow_missing_digests=allow_missing):
  File "/usr/lib64/python2.7/site-packages/portage/package/ebuild/fetch.py", 
line 520, in fetch
    if _userpriv_test_write_file(mysettings, write_test_file):
  File "/usr/lib64/python2.7/site-packages/portage/package/ebuild/fetch.py", 
line 134, in _userpriv_test_write_file
    returncode = _spawn_fetch(settings, args)
  File "/usr/lib64/python2.7/site-packages/portage/package/ebuild/fetch.py", 
line 87, in _spawn_fetch
    settings["PORTAGE_FETCH_T"])
  File "/usr/lib64/python2.7/site-packages/portage/_selinux.py", line 122, in 
__init__
    self._con = settype(selinux_type)
  File "/usr/lib64/python2.7/site-packages/portage/_selinux.py", line 76, in 
settype
    ret[2] = newtype
IndexError: list assignment index out of range

Signed-off-by: Jason Zaman <perfinion <AT> gentoo.org>

 pym/portage/_selinux.py | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/pym/portage/_selinux.py b/pym/portage/_selinux.py
index c5e8b2c..985e966 100644
--- a/pym/portage/_selinux.py
+++ b/pym/portage/_selinux.py
@@ -6,6 +6,7 @@
 import os
 import shutil
 import sys
+import warnings
 
 import portage
 from portage import _encodings
@@ -72,9 +73,13 @@ def rename(src, dest):
                setfscreate()
 
 def settype(newtype):
-       ret = getcontext().split(":")
-       ret[2] = newtype
-       return ":".join(ret)
+       try:
+               ret = getcontext().split(":")
+               ret[2] = newtype
+               return ":".join(ret)
+       except IndexError:
+               warnings.warn("Invalid SELinux context: %s" % getcontext())
+               return None
 
 def setexec(ctx="\n"):
        ctx = _native_string(ctx, encoding=_encodings['content'], 
errors='strict')
@@ -122,15 +127,16 @@ class spawn_wrapper(object):
                self._con = settype(selinux_type)
 
        def __call__(self, *args, **kwargs):
+               if self._con is not None:
+                       pre_exec = kwargs.get("pre_exec")
 
-               pre_exec = kwargs.get("pre_exec")
+                       def _pre_exec():
+                               if pre_exec is not None:
+                                       pre_exec()
+                               setexec(self._con)
 
-               def _pre_exec():
-                       if pre_exec is not None:
-                               pre_exec()
-                       setexec(self._con)
+                       kwargs["pre_exec"] = _pre_exec
 
-               kwargs["pre_exec"] = _pre_exec
                return self._spawn_func(*args, **kwargs)
 
 def symlink(target, link, reflnk):

Reply via email to