From: "Kipp N. Davis" <kippndavis.work@xxxxxxx> These tests exercise new SELinux hooks for firmware_load, kexec_image_load, kexec_initramfs_load, and policy_load alongside module_load. These tests depend on the corresponding kernel patch and updating the base policy to define the new system permissions. If the kernel does not support them, they will be skipped. For testing purposes, you can update the base policy by manually modifying your base module and tweaking /usr/share/selinux/devel (latter only required due to writing the test policy as a .te file rather than as a .cil in order to use the test macros) as follows: sudo semodule -c -E base sudo sed -i.orig \ "s/module_load/module_load firmware_load kexec_image_load \ kexec_initramfs_load policy_load x509_certificate_load/" base.cil sudo semodule -i base.cil sudo sed -i.orig \ "s/module_load/module_load firmware_load kexec_image_load \ kexec_initramfs_load policy_load x509_certificate_load/" \ /usr/share/selinux/devel/include/support/all_perms.spt When finished testing, you can sudo semodule -r base to undo the module change and restore your all_perms.spt file from the saved .orig file. Note: The x509_certificate_load permission is newly added in the kernel but is not tested here due to no callers remaining after boot. Signed-off-by: Kipp Davis <kippndavis.work@xxxxxxx> --- policy/Makefile | 8 ++ policy/test_file_load.te | 102 +++++++++++++++++++++++ tests/module_load/Makefile | 2 +- tests/module_load/setest_firmware_load.c | 29 +++++++ tests/module_load/test | 70 +++++++++++++++- 5 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 policy/test_file_load.te create mode 100644 tests/module_load/setest_firmware_load.c diff --git a/policy/Makefile b/policy/Makefile index 46e51f3..fcc80f0 100644 --- a/policy/Makefile +++ b/policy/Makefile @@ -180,6 +180,14 @@ ifeq ($(shell [ $(POL_VERS) -ge 34 -a $(MAX_KERNEL_POLICY) -ge 34 ] && echo true TARGETS += test_ioctl_cond_xperms.te endif +ifeq ($(shell grep -q firmware_load $(POLDEV)/include/support/all_perms.spt && \ + grep -q kexec_image_load $(POLDEV)/include/support/all_perms.spt && \ + grep -q kexec_initramfs_load $(POLDEV)/include/support/all_perms.spt && \ + grep -q policy_load $(POLDEV)/include/support/all_perms.spt && \ + echo true),true) +TARGETS += test_file_load.te +endif + all: build expand_check: diff --git a/policy/test_file_load.te b/policy/test_file_load.te new file mode 100644 index 0000000..e98503a --- /dev/null +++ b/policy/test_file_load.te @@ -0,0 +1,102 @@ +###################### Test file loading ################### + +require { + type boot_t; + type kdump_exec_t; + type tmpfs_t; + type user_tmp_t; +} + +###################### Allow sys kexec_image_load ###################### +type test_kexec_allow_kexec_image_load_t; +testsuite_domain_type_minimal(test_kexec_allow_kexec_image_load_t); + +files_search_boot(test_kexec_allow_kexec_image_load_t); +fs_rw_inherited_tmpfs_files(test_kexec_allow_kexec_image_load_t); +exec_files_pattern(test_kexec_allow_kexec_image_load_t, kdump_exec_t, kdump_exec_t); +domain_entry_file(test_kexec_allow_kexec_image_load_t, kdump_exec_t); +allow test_kexec_allow_kexec_image_load_t self:capability sys_boot; + +allow test_kexec_allow_kexec_image_load_t boot_t:system kexec_image_load; +allow test_kexec_allow_kexec_image_load_t tmpfs_t:system kexec_image_load; + +###################### Deny sys kexec_image_load ###################### +type test_kexec_deny_kexec_image_load_t; +testsuite_domain_type_minimal(test_kexec_deny_kexec_image_load_t); + +files_search_boot(test_kexec_deny_kexec_image_load_t); +fs_rw_inherited_tmpfs_files(test_kexec_deny_kexec_image_load_t); +exec_files_pattern(test_kexec_deny_kexec_image_load_t, kdump_exec_t, kdump_exec_t); +domain_entry_file(test_kexec_deny_kexec_image_load_t, kdump_exec_t); +allow test_kexec_deny_kexec_image_load_t self:capability sys_boot; + +neverallow test_kexec_deny_kexec_image_load_t boot_t:system kexec_image_load; +neverallow test_kexec_deny_kexec_image_load_t tmpfs_t:system kexec_image_load; + +###################### Allow sys kexec_initramfs_load ###################### +type test_kexec_allow_kexec_initramfs_load_t; +testsuite_domain_type_minimal(test_kexec_allow_kexec_initramfs_load_t); + +files_search_boot(test_kexec_allow_kexec_initramfs_load_t); +fs_rw_inherited_tmpfs_files(test_kexec_allow_kexec_initramfs_load_t); +domain_entry_file(test_kexec_allow_kexec_initramfs_load_t, kdump_exec_t); +allow test_kexec_allow_kexec_initramfs_load_t self:capability sys_boot; + +allow test_kexec_allow_kexec_initramfs_load_t boot_t:system { kexec_image_load kexec_initramfs_load } ; +allow test_kexec_allow_kexec_initramfs_load_t tmpfs_t:system { kexec_image_load kexec_initramfs_load }; + +###################### Deny sys kexec_initramfs_load ###################### +type test_kexec_deny_kexec_initramfs_load_t; +testsuite_domain_type_minimal(test_kexec_deny_kexec_initramfs_load_t); + +files_search_boot(test_kexec_deny_kexec_initramfs_load_t); +fs_rw_inherited_tmpfs_files(test_kexec_deny_kexec_initramfs_load_t); +domain_entry_file(test_kexec_deny_kexec_initramfs_load_t, kdump_exec_t); +allow test_kexec_deny_kexec_initramfs_load_t boot_t:system kexec_image_load; +allow test_kexec_deny_kexec_initramfs_load_t tmpfs_t:system kexec_image_load; +allow test_kexec_deny_kexec_initramfs_load_t self:capability sys_boot; + +neverallow test_kexec_deny_kexec_initramfs_load_t boot_t:system kexec_initramfs_load; +neverallow test_kexec_deny_kexec_initramfs_load_t tmpfs_t:system kexec_initramfs_load; + +###################### Allow sys firmware_load ###################### +type test_kmodule_allow_firmware_load_t; +testsuite_domain_type_minimal(test_kmodule_allow_firmware_load_t) +typeattribute test_kmodule_allow_firmware_load_t kmoduledomain; + +type firmware_allow_file_t; +files_type(firmware_allow_file_t); + +allow test_kmodule_allow_firmware_load_t self:capability sys_module; +allow test_kmodule_allow_firmware_load_t test_file_t:system module_load; +allow test_kmodule_allow_firmware_load_t self:system module_load; +allow kernel_t firmware_allow_file_t:system firmware_load; + +###################### Deny sys firmware_load ###################### +type test_kmodule_deny_firmware_load_t; +testsuite_domain_type_minimal(test_kmodule_deny_firmware_load_t) +typeattribute test_kmodule_deny_firmware_load_t kmoduledomain; + +type firmware_deny_file_t; +files_type(firmware_deny_file_t); + +allow test_kmodule_deny_firmware_load_t self:capability { sys_module }; +allow test_kmodule_deny_firmware_load_t test_file_t:system { module_load }; +allow test_kmodule_deny_firmware_load_t self:system { module_load }; +neverallow kernel_t firmware_deny_file_t:system firmware_load; + +###################### Allow sys policy_load ###################### +type test_policy_allow_policy_load_t; +testsuite_domain_type_minimal(test_policy_allow_policy_load_t); + +userdom_read_inherited_user_tmp_files(test_policy_allow_policy_load_t); +userdom_write_user_tmp_files(test_policy_allow_policy_load_t); +allow test_policy_allow_policy_load_t user_tmp_t:system policy_load; + +###################### Deny sys policy_load ###################### +type test_policy_deny_policy_load_t; +testsuite_domain_type_minimal(test_policy_deny_policy_load_t); + +userdom_read_inherited_user_tmp_files(test_policy_deny_policy_load_t); +userdom_write_user_tmp_files(test_policy_deny_policy_load_t); +neverallow test_policy_deny_policy_load_t user_tmp_t:system policy_load; diff --git a/tests/module_load/Makefile b/tests/module_load/Makefile index 0839532..fc93aec 100644 --- a/tests/module_load/Makefile +++ b/tests/module_load/Makefile @@ -1,4 +1,4 @@ -obj-m = setest_module_load.o setest_module_request.o +obj-m = setest_module_load.o setest_module_request.o setest_firmware_load.o TARGETS = finit_load init_load LDLIBS += -lselinux diff --git a/tests/module_load/setest_firmware_load.c b/tests/module_load/setest_firmware_load.c new file mode 100644 index 0000000..d67470b --- /dev/null +++ b/tests/module_load/setest_firmware_load.c @@ -0,0 +1,29 @@ +#include <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/firmware.h> + +static int __init setest_firmware_request_init(void) +{ + const struct firmware *fw; + int result; + + pr_info("INIT - setest_firmware_request\n"); + result = request_firmware(&fw, "dummy-firmware", NULL); + if (result) { + pr_err("request_firmware failed: %d\n", result); + return result; + } + pr_info("request_firmware succeeded\n"); + release_firmware(fw); + return 0; +} + +static void __exit setest_firmware_request_exit(void) +{ + pr_info("EXIT - setest_firmware_request\n"); +} + +module_init(setest_firmware_request_init); +module_exit(setest_firmware_request_exit); +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/tests/module_load/test b/tests/module_load/test index 524b333..98c5946 100755 --- a/tests/module_load/test +++ b/tests/module_load/test @@ -16,7 +16,13 @@ BEGIN { $v = " "; } - plan tests => 8; + $kexec_perm_file = "/sys/fs/selinux/class/system/perms/kexec_image_load"; + $kexec_load_exists = 0; + if ( -f $kexec_perm_file ) { + $kexec_load_exists = 1; + } + + plan tests => 17; } print "Test finit_module(2)\n"; @@ -59,4 +65,66 @@ $result = system "runcon -t test_kmodule_deny_module_request_t $basedir/init_load $v $basedir setest_module_request 2>&1"; ok( $result >> 8 eq 13 ); +SKIP: { + skip( +"Not all system permissions available; skipping kexec, initramfs, firmware and policy tests", + 9 + ) unless $kexec_load_exists; + + $kver = `uname -r`; + chomp($kver); + $kernel = "/boot/vmlinuz-$kver"; + $initrd = "/boot/initramfs-$kver.img"; + + $result = + system "runcon -t test_kexec_allow_kexec_image_load_t kexec -l $kernel"; + ok( $result eq 0 ); + + $result = system "runcon -t test_kexec_allow_kexec_image_load_t kexec -u"; + ok( $result eq 0 ); + + # Deny system { kexec_image_load } + $result = system + "runcon -t test_kexec_deny_kexec_image_load_t kexec -l $kernel 2>&1"; + ok( $result >> 8 eq 255 ); + + $result = system +"runcon -t test_kexec_allow_kexec_initramfs_load_t kexec -l --initrd=$initrd $kernel"; + ok( $result eq 0 ); + + # Deny system { kexec_initramfs_load } + $result = system +"runcon -t test_kexec_deny_kexec_initramfs_load_t kexec -l --initrd=$initrd $kernel 2>&1"; + ok( $result >> 8 eq 255 ); + + system("mkdir -p /usr/lib/firmware"); + system("echo 'Test firmware' > /usr/lib/firmware/dummy-firmware"); + system("chcon -t firmware_allow_file_t /usr/lib/firmware/dummy-firmware"); + + $result = system +"runcon -t test_kmodule_allow_firmware_load_t $basedir/init_load $v $basedir setest_firmware_load"; + ok( $result eq 0 ); + + system("chcon -t firmware_deny_file_t /usr/lib/firmware/dummy-firmware"); + + # Deny system { firmware_load } - EACCES + $result = system +"runcon -t test_kmodule_deny_firmware_load_t $basedir/init_load $v $basedir setest_firmware_load 2>&1"; + ok( $result >> 8 eq 13 ); + + system("rm -f /usr/lib/firmware/dummy-firmware"); + system("echo 'measure func=BPRM_CHECK' > /tmp/test_ima_policy"); + + $result = system +qq(runcon -t test_policy_allow_policy_load_t bash -c "echo '/tmp/test_ima_policy' > /sys/kernel/security/ima/policy"); + ok( $result eq 0 ); + + # Deny system { policy_load } - EACCES + $result = system +qq(runcon -t test_policy_deny_policy_load_t bash -c "echo '/tmp/test_ima_policy' > /sys/kernel/security/ima/policy 2>&1"); + ok( $result >> 8 eq 1 ); + + system("rm -f /tmp/test_ima_policy"); +} + exit; -- 2.48.1