From d9ed29d74eff813f341a0fe19f27732a07fa7c36 Mon Sep 17 00:00:00 2001 From: Vit Mojzis Date: Wed, 16 Jul 2025 11:45:59 +0200 Subject: [PATCH 1/2] Add test for attribute assignment to attributes Replicate two tests, but all access (including assignment to attributes like domain) is assigned via proxy attributes -- attributes are used in place of the original types and types used in the tests are assigned to the proxy attributes (no access is assigned directly to the types). The following checkpolicy patch is needed to compile the test policy: https://lore.kernel.org/selinux/20250623102726.3818713-1-vmojzis@redhat.com/ Checkpolicy builds with the patch applied are available in: https://copr.fedorainfracloud.org/coprs/vmojzis/userspace_test/ TODO: the test needs to be made conditional on userspace version Signed-off-by: Vit Mojzis --- policy/Makefile | 3 +- policy/test_attribute_assignment.te | 67 +++++++++++++++++++++++++++ tests/Makefile | 3 +- tests/attribute_assignment/.gitignore | 1 + tests/attribute_assignment/Makefile | 5 ++ tests/attribute_assignment/source.c | 30 ++++++++++++ tests/attribute_assignment/test | 42 +++++++++++++++++ 7 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 policy/test_attribute_assignment.te create mode 100644 tests/attribute_assignment/.gitignore create mode 100644 tests/attribute_assignment/Makefile create mode 100644 tests/attribute_assignment/source.c create mode 100755 tests/attribute_assignment/test diff --git a/policy/Makefile b/policy/Makefile index ffd774d9..6937614b 100644 --- a/policy/Makefile +++ b/policy/Makefile @@ -29,7 +29,8 @@ TARGETS = \ test_task_getsid.te test_task_setpgid.te test_task_setsched.te \ test_transition.te test_unix_socket.te \ test_mmap.te test_overlayfs.te test_mqueue.te \ - test_ibpkey.te test_atsecure.te test_cgroupfs.te + test_ibpkey.te test_atsecure.te test_cgroupfs.te \ + test_attribute_assignment.te ifeq (x$(DISTRO),$(filter x$(DISTRO),xRHEL4 xRHEL5 xRHEL6)) SUPPORTS_CIL = n diff --git a/policy/test_attribute_assignment.te b/policy/test_attribute_assignment.te new file mode 100644 index 00000000..b8dd8f5d --- /dev/null +++ b/policy/test_attribute_assignment.te @@ -0,0 +1,67 @@ +########################################## +# +# Policy for testing attribute assignment to attributes +# + +# 4 attributtes linked in a typeattribute sequence d->c->b->a +attribute test_attribute_a; +attribute test_attribute_b; +attribute test_attribute_c; +attribute test_attribute_d; + +typeattribute test_attribute_b test_attribute_a; +typeattribute test_attribute_c test_attribute_b; +typeattribute test_attribute_d test_attribute_c; + +# 2 types assigned to attributes b and d +type test_attribute_setpgid_yes_t; +type test_attribute_setpgid_no_t; + +typeattribute test_attribute_setpgid_no_t test_attribute_b; +typeattribute test_attribute_setpgid_yes_t test_attribute_d; + +# Attribute "a" is made into a minimal domain type +testsuite_domain_type_minimal(test_attribute_a) +# Attribute "c" and types assigned to it can change its pgid +testsuite_domain_type(test_attribute_c) + +# Allow each attribute some access so that they don't get optimized out +allow test_attribute_a test_attribute_a:dir getattr; +allow test_attribute_b test_attribute_b:dir getattr; +allow test_attribute_c test_attribute_c:dir getattr; +allow test_attribute_d test_attribute_d:dir getattr; + +########################################## +# +# repeats entrypoint test, only with attributes as proxies for every type +# + +# Type that the test domain can be entered through +attribute test_attribute_entrypoint; +files_type(test_attribute_entrypoint) + +# Type that the test domain can NOT be entered through +attribute test_attribute_entrypoint_deny; +files_type(test_attribute_entrypoint_deny) + +# Test domain that can only be entered via test_attribute_entrypoint +attribute test_attribute_domain; +testsuite_domain_type(test_attribute_domain) + +# Allow test_attribute_domain to be entered via test_attribute_entrypoint. +domain_entry_file(test_attribute_domain, test_attribute_entrypoint) + +# Allow test_attribute_domain to execute test_attribute_entrypoint_deny, but not +# to enter through it +can_exec(test_attribute_domain, test_entrypoint_deny_t) + +# assign corresponding types +type test_attribute_entrypoint_t; +typeattribute test_attribute_entrypoint_t test_attribute_entrypoint; + +type test_attribute_entrypoint_deny_t; +typeattribute test_attribute_entrypoint_deny_t test_attribute_entrypoint_deny; + +type test_attribute_domain_t; +typeattribute test_attribute_domain_t test_attribute_domain; + diff --git a/tests/Makefile b/tests/Makefile index 7a6aace1..cf7ccada 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -28,7 +28,8 @@ SUBDIRS:= domain_trans entrypoint execshare exectrace execute_no_trans \ task_getpgid task_setpgid file ioctl capable_file capable_net \ capable_sys dyntrans dyntrace bounds nnp_nosuid mmap unix_socket \ inet_socket/tcp inet_socket/udp overlay checkreqprot mqueue \ - mac_admin atsecure infiniband_endport infiniband_pkey + mac_admin atsecure infiniband_endport infiniband_pkey \ + attribute_assignment ifeq ($(shell grep -q cap_userns $(POLDEV)/include/support/all_perms.spt && echo true),true) ifneq ($(shell ./kvercmp $$(uname -r) 4.7),-1) diff --git a/tests/attribute_assignment/.gitignore b/tests/attribute_assignment/.gitignore new file mode 100644 index 00000000..5a18cd2f --- /dev/null +++ b/tests/attribute_assignment/.gitignore @@ -0,0 +1 @@ +source diff --git a/tests/attribute_assignment/Makefile b/tests/attribute_assignment/Makefile new file mode 100644 index 00000000..48e25372 --- /dev/null +++ b/tests/attribute_assignment/Makefile @@ -0,0 +1,5 @@ +TARGETS=source + +all: $(TARGETS) +clean: + rm -f $(TARGETS) diff --git a/tests/attribute_assignment/source.c b/tests/attribute_assignment/source.c new file mode 100644 index 00000000..3069a6a7 --- /dev/null +++ b/tests/attribute_assignment/source.c @@ -0,0 +1,30 @@ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include +#include +#include + +int main(void) +{ + pid_t pid, group_id; + + pid = getpid(); + if ((group_id = getpgid(pid)) < 0) { + perror("getpgid"); + exit(-1); + } + printf("Group ID = %d\n", group_id); + if (setpgid(pid, pid) < 0) { + perror("setpgid"); + exit(1); + } + if ((group_id = getpgid(pid)) < 0) { + perror("getpgid"); + exit(-1); + } + printf("Group ID = %d\n", group_id); + printf("pid = %d\n", pid); + exit(0); +} diff --git a/tests/attribute_assignment/test b/tests/attribute_assignment/test new file mode 100755 index 00000000..c0bc9c76 --- /dev/null +++ b/tests/attribute_assignment/test @@ -0,0 +1,42 @@ +#!/usr/bin/perl + +use Test; +BEGIN { plan tests => 4 } + +# task_getpgid, but all permissions are assigned using attributes (two step transition) + +$basedir = $0; +$basedir =~ s|(.*)/[^/]*|$1|; + +# Verify that test_setpgid_yes_t can setpgid. +$result = + system("runcon -t test_attribute_setpgid_yes_t -- $basedir/source 2>&1"); +ok( $result, 0 ); + +# Verify that test_setpgid_no_t cannot setpgid. +$result = + system("runcon -t test_attribute_setpgid_no_t -- $basedir/source 2>&1"); +ok($result); + +# entrypoint test, but all permissions are passed using attributes + +$basedir = $0; +$basedir =~ s|(.*)/[^/]*|$1|; + +system("cp /bin/true $basedir/true"); + +# Verify that test_attribute_domain_t cannot be entered via test_attribute_entrypoint_deny_t. +system("chcon -t test_attribute_entrypoint_deny_t $basedir/true"); +$result = system("runcon -t test_attribute_domain_t $basedir/true 2>&1"); +ok($result); #this should fail + +# Verify that test_attribute_domain_t can be entered via test_attribute_entrypoint_t. +system("chcon -t test_attribute_entrypoint_t $basedir/true"); +$result = system("runcon -t test_attribute_domain_t $basedir/true"); +ok( $result, 0 ); #this should pass + +# Cleanup. +system("rm -f $basedir/true"); + +exit; + From 2e2aaf4868fc1ee86ccac16e6c579a2da8011a5a Mon Sep 17 00:00:00 2001 From: Vit Mojzis Date: Wed, 16 Jul 2025 11:59:45 +0200 Subject: [PATCH 2/2] [DO NOT MERGE] Temporary hack to run attribute assignment test Signed-off-by: Vit Mojzis --- tmt/tests.fmf | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tmt/tests.fmf b/tmt/tests.fmf index 64c7c406..86a7fe39 100644 --- a/tmt/tests.fmf +++ b/tmt/tests.fmf @@ -24,7 +24,11 @@ exit 1 ;; esac - + dnf copr enable -y vmojzis/userspace_test + dnf install -y checkpolicy + dnf list --showduplicates checkpolicy + dnf update -y checkpolicy + rpm -qa checkpolicy case "$STS_KERNEL" in default|'') dnf install -y kernel-modules-$(uname -r) kernel-devel-$(uname -r)