Skip to content

Commit

Permalink
Set SELinux contexts of dom0-provided kernels
Browse files Browse the repository at this point in the history
This is necessary for qubes to work with SELinux enforcing, and fixes
several bugs that appear even when SELinux is not enforcing.

Fixes QubesOS/qubes-issues#4278
Fixes QubesOS/qubes-issues#5765
  • Loading branch information
DemiMarie committed Dec 2, 2021
1 parent 392f829 commit b4d6a5f
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
85 changes: 85 additions & 0 deletions genattr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/usr/bin/python3 --
import subprocess, os, sys, re, tempfile
def main(argv, write_cmd, read_cmd, expected_stdout):
match_re = re.compile(r'\A[A-Za-z0-9._/+,-]+\Z')
write_cmd.write('set_current_time 1\n'
'ea_set / security.selinux system_u:object_r:modules_dep_t:s0\n')
read_cmd.write('ea_get / security.selinux\n')
expected_stdout.write('debugfs: ea_get / security.selinux\n'
'security.selinux (34) = "system_u:object_r:modules_dep_t:s0"\n\n')
def bad(e):
raise e
def emit(dirpath, name):
path = os.path.join(dirpath, name)
context = 'modules_object_t'
if path.startswith(argv + '/build'):
context = 'usr_t'
elif dirpath == argv:
if name.startswith('modules.'):
context = 'modules_dep_t'
elif name == 'build':
context = 'usr_t'
context = ':'.join(('system_u', 'object_r', context, 's0'))
write_cmd.write('ea_set /%s security.selinux %s\n' % (path, context))
read_cmd.write('ea_get /%s security.selinux\n' % (path,))
expected_stdout.write('''debugfs: ea_get /%s security.selinux
security.selinux (%d) = "%s"
''' % (path, len(context), context))
for dirpath, dirnames, filenames in os.walk(argv, onerror=bad, topdown=True):
for i in dirnames:
if not match_re.match(i):
raise ValueError("Invalid directory name %r" % os.path.join(dirpath, i))
emit(dirpath, i)
for i in filenames:
if not match_re.match(i):
raise ValueError("Invalid filename name %r" % os.path.join(dirpath, i))
emit(dirpath, i)
if __name__ == '__main__':
os.chdir(sys.argv[1])
with tempfile.TemporaryDirectory() as d, \
open(os.path.join(d, 'write_cmd'), 'w') as write_cmd, \
open(os.path.join(d, 'read_cmd'), 'w') as read_cmd, \
open(os.path.join(d, 'expected_stdout'), 'w') as expected_stdout, \
open(os.path.join(d, 'actual_stdout'), 'w') as actual_stdout, \
open(os.path.join(d, 'clear_timestamps'), 'w') as clear_timestamps:
main(sys.argv[2], write_cmd, read_cmd, expected_stdout)
write_cmd.write("""
set_super_value mtime 1
set_super_value lastcheck 1
set_super_value mkfs_time 1
set_super_value first_error_time 1
set_super_value last_error_time 1
set_current_time 1
set_super_value wtime 1
dirty -clean
close
""")
clear_timestamps.write("""
set_super_value mtime 1
set_super_value lastcheck 1
set_super_value mkfs_time 1
set_super_value first_error_time 1
set_super_value last_error_time 1
set_current_time 1
set_super_value wtime 1
dirty -clean
close
""")
clear_timestamps.flush()
write_cmd.flush()
read_cmd.flush()
expected_stdout.flush()
subprocess.check_call(('debugfs', '-w', '-f', write_cmd.name, '--', sys.argv[3]), stdout=subprocess.DEVNULL)
subprocess.check_call(('e2fsck', '-pDfE', 'optimize_extents', '--', sys.argv[3]))
if False: # This breaks determinism, sadly
subprocess.check_call(('debugfs', '-w', '-f', clear_timestamps.name, '--', sys.argv[3]))
subprocess.check_call(('resize2fs', '-M', '--', sys.argv[3]))
subprocess.check_call(('e2fsck', '-pDfE', 'optimize_extents', '--', sys.argv[3]))
for i in (0, 0x8000, 0x18000):
subprocess.check_call(('debugfs', '-w', '-f', clear_timestamps.name, '-b4096', '-s' + str(i), '--', sys.argv[3]))
subprocess.check_call(('debugfs', '-f', read_cmd.name, '--', sys.argv[3]), stdout=actual_stdout)
subprocess.check_call(('e2fsck', '-n', '--', sys.argv[3]))
subprocess.check_call(('fallocate', '--dig-holes', '--', sys.argv[3]))
# If the labels weren't set properly, fail the build
subprocess.check_call(('diff', '-u', '--', expected_stdout.name, actual_stdout.name))
7 changes: 7 additions & 0 deletions kernel.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -502,9 +502,16 @@ if [ -n "$SOURCE_DATE_EPOCH" ]; then
find %buildroot%vm_install_dir/modules \
-exec touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" {} +
fi

PATH="/sbin:$PATH" mkfs.ext3 -d %buildroot%vm_install_dir/modules \
-U dcee2318-92bd-47a5-a15d-e79d1412cdce \
%buildroot%vm_install_dir/modules.img 1024M

# Set up SELinux labels on the files, so that qubes with SELinux enforcing work
PATH="/sbin:$PATH" python3 ./genattr.py %upstream_version-%plainrel \
%buildroot%vm_install_dir/modules \
"$PWD/%buildroot%vm_install_dir/modules.img" || exit

rm -rf %buildroot%vm_install_dir/modules

# remove files that will be auto generated by depmod at rpm -i time
Expand Down

0 comments on commit b4d6a5f

Please sign in to comment.