Skip to content

Commit

Permalink
check SELinux status before build libear
Browse files Browse the repository at this point in the history
  • Loading branch information
rizsotto committed Jan 5, 2016
1 parent 949dc05 commit 17c041f
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 20 deletions.
26 changes: 18 additions & 8 deletions libscanbuild/intercept.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ def post_processing(commands):
previous = iter([])
# filter out duplicate entries from both
duplicate = duplicate_check(entry_hash)
return (entry
for entry in itertools.chain(previous, current)
return (entry for entry in itertools.chain(previous, current)
if os.path.exists(entry['file']) and not duplicate(entry))

with TemporaryDirectory(prefix='intercept-', dir=tempdir()) as tmp_dir:
Expand Down Expand Up @@ -123,8 +122,8 @@ def setup_environment(args, destination, bin_dir):
c_compiler = args.cc if 'cc' in args else 'cc'
cxx_compiler = args.cxx if 'cxx' in args else 'c++'

libear_path = None if args.override_compiler or is_sip_enabled() else \
build_libear(c_compiler, destination)
libear_path = None if args.override_compiler or is_preload_disabled(
sys.platform) else build_libear(c_compiler, destination)

environment = dict(os.environ)
environment.update({'INTERCEPT_BUILD_TARGET_DIR': destination})
Expand Down Expand Up @@ -252,16 +251,27 @@ def is_compiler_call(entry):
return any((pattern.match(executable) for pattern in patterns))


def is_sip_enabled():
def is_preload_disabled(platform):
""" Library-based interposition will fail silently if SIP is enabled,
so this should be detected. You can detect whether SIP is enabled on
Darwin by checking whether (1) there is a binary called 'csrutil' in
the path and, if so, (2) whether the output of executing 'csrutil status'
contains 'System Integrity Protection status: enabled'. """
contains 'System Integrity Protection status: enabled'.
Same problem on linux when SELinux is enabled. The status query program
'sestatus' and the output when it's enabled 'SELinux status: enabled'. """

if platform == 'darwin':
pattern = re.compile(r'System Integrity Protection status:\s+enabled')
command = ['csrutil', 'status']
elif platform in {'linux', 'linux2'}:
pattern = re.compile(r'SELinux status:\s+enabled')
command = ['sestatus']
else:
return False

pattern = re.compile(r'System Integrity Protection status: enabled')
try:
lines = subprocess.check_output(['csrutil', 'status']).decode('utf-8')
lines = subprocess.check_output(command).decode('utf-8')
return any((pattern.match(line) for line in lines.splitlines()))
except:
return False
Expand Down
50 changes: 38 additions & 12 deletions tests/unit/test_intercept.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,36 +62,62 @@ def test(command):
'/opt/file.c')

def test_sip(self):
def create_csrutil(dest_dir, enabled):
filename = os.path.join(dest_dir, 'csrutil')
def create_status_report(filename, message):
content = """#!/usr/bin/env sh
echo 'bla-bla-bla'
echo 'System Integrity Protection status: {0}'
echo 'sa-la-la-la'
""".format('enabled' if enabled else 'disabled')
echo 'la-la-la'
echo '{0}'
echo 'sa-la-la-la'
echo 'la-la-la'
""".format(message)
lines = [line.strip() for line in content.split('\n')]
with open(filename, 'w') as handle:
handle.write('\n'.join(lines))
handle.close()
os.chmod(filename, 0x1ff)

def create_csrutil(dest_dir, status):
filename = os.path.join(dest_dir, 'csrutil')
message = 'System Integrity Protection status: {0}'.format(status)
return create_status_report(filename, message)

def create_sestatus(dest_dir, status):
filename = os.path.join(dest_dir, 'sestatus')
message = 'SELinux status:\t{0}'.format(status)
return create_status_report(filename, message)

ENABLED = 'enabled'
DISABLED = 'disabled'

OSX = 'darwin'
LINUX = 'linux'

with fixtures.TempDir() as tmpdir:
try:
saved = os.environ['PATH']
os.environ['PATH'] = tmpdir + ':' + saved
# shall be true when enabled
create_csrutil(tmpdir, True)
self.assertTrue(sut.is_sip_enabled())
# shall be false when disabled
create_csrutil(tmpdir, False)
self.assertFalse(sut.is_sip_enabled())

create_csrutil(tmpdir, ENABLED)
self.assertTrue(sut.is_preload_disabled(OSX))

create_csrutil(tmpdir, DISABLED)
self.assertFalse(sut.is_preload_disabled(OSX))

create_sestatus(tmpdir, ENABLED)
self.assertTrue(sut.is_preload_disabled(LINUX))

create_sestatus(tmpdir, DISABLED)
self.assertFalse(sut.is_preload_disabled(LINUX))
finally:
os.environ['PATH'] = saved

try:
saved = os.environ['PATH']
os.environ['PATH'] = ''
# shall be false when it's not in the path
self.assertFalse(sut.is_sip_enabled())
self.assertFalse(sut.is_preload_disabled(OSX))
self.assertFalse(sut.is_preload_disabled(LINUX))

self.assertFalse(sut.is_preload_disabled('unix'))
finally:
os.environ['PATH'] = saved

0 comments on commit 17c041f

Please sign in to comment.