From 5c17df02195e091a2d293963417d5d11c95f8621 Mon Sep 17 00:00:00 2001 From: Zygmunt Krynicki Date: Fri, 17 Jan 2025 08:19:42 +0100 Subject: [PATCH 1/3] profiles: attach toybox profile to /usr/bin/toybox This is the actual path used on Debian and derivatives. Signed-off-by: Zygmunt Krynicki --- profiles/apparmor.d/toybox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/profiles/apparmor.d/toybox b/profiles/apparmor.d/toybox index 7921fd874..e384606e3 100644 --- a/profiles/apparmor.d/toybox +++ b/profiles/apparmor.d/toybox @@ -4,7 +4,7 @@ abi , include -profile toybox /bin/toybox flags=(unconfined) { +profile toybox /usr/bin/toybox flags=(unconfined) { userns, # Site-specific additions and overrides. See local/README for details. From 2ab2c8f8a15f0b4cb527f9198c90b8c50e9e1bfb Mon Sep 17 00:00:00 2001 From: Zygmunt Krynicki Date: Tue, 21 Jan 2025 12:32:55 +0100 Subject: [PATCH 2/3] tests: add suite with profile tests Hopefully more and more profiles will come with smoke tests. Since the pattern of those tests is likely to be very similar (compile profile, run some programs, remove profile) it will be good to check if the profile had caused any denials to be logged. Having this at the suite level should make writing actual tests easier. The prepare-each and restore-each logic compile the profile, check for errors and finally remove the profile. The debug-each logic shows the program name (with full path). Signed-off-by: Zygmunt Krynicki --- spread.yaml | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/spread.yaml b/spread.yaml index 015b85e08..e0eed9013 100644 --- a/spread.yaml +++ b/spread.yaml @@ -117,6 +117,72 @@ debug-each: | uname -a suites: + tests/profiles/: + summary: Tests that exercise specific application profiles + # variables: + # PROFILE_NAME: name of the profile on disk + # PROGRAM_NAME: name of the program to execute + prepare-each: | + rm -f denials.txt + + # Disable rate-limiting so that we see all denials. + sysctl --values kernel.printk_ratelimit >old-ratelimit.txt + sysctl --write kernel.printk_ratelimit=0 + + # Stop auditd so that all denials end up in the ring buffer. + if [ "$(systemctl is-active auditd.service)" != inactive ]; then + systemctl stop auditd.service + touch did-stop-auditd.txt + fi + + # Clear the kernel ring buffer. + dmesg --clear + + # Compute profile name from the name of the task. + echo "PROFILE_NAME=${PROFILE_NAME:=$(basename "$SPREAD_TASK")}" + + "$SPREAD_PATH"/parser/apparmor_parser \ + --warn=all \ + --replace \ + --skip-cache \ + --base="$SPREAD_PATH"/profiles/apparmor.d \ + "$SPREAD_PATH"/profiles/apparmor.d/"$PROFILE_NAME" 2>parser.txt + if [ -s parser.txt ]; then + echo "Parser produced warnings:" + cat parser.txt + exit 1 + fi + + restore-each: | + # Compute profile name from the name of the task. + echo "PROFILE_NAME=${PROFILE_NAME:=$(basename "$SPREAD_TASK")}" + + "$SPREAD_PATH"/parser/apparmor_parser \ + --base="$SPREAD_PATH"/profiles/apparmor.d \ + --remove \ + "$SPREAD_PATH"/profiles/apparmor.d/"$PROFILE_NAME" + + # Restore auditd and old rate-limit. + if [ -f did-stop-auditd.txt ]; then + systemctl start auditd.service + rm -f did-stop-auditd.txt + fi + if [ -f old-ratelimit.txt ]; then + sysctl -w kernel.printk_ratelimit="$(cat old-ratelimit.txt)" + rm -f old-ratelimit.txt + fi + + # Check if running the test resulted in any logged denials. + if dmesg | grep DENIED > denials.txt; then + echo "Denials were emitted during the test" + cat denials.txt + exit 1 + fi + + debug-each: | + echo "PROGRAM_NAME=${PROGRAM_NAME:=$(basename "$SPREAD_TASK")}" + command -v "$PROGRAM_NAME" + utils/: summary: Unit tests for the Python utilities. prepare: | From be47567d2756c607997636202629db79560319f1 Mon Sep 17 00:00:00 2001 From: Zygmunt Krynicki Date: Thu, 16 Jan 2025 16:37:38 +0100 Subject: [PATCH 3/3] tests: add integration test for toybox Signed-off-by: Zygmunt Krynicki --- .image-garden.mk | 1 + tests/profiles/toybox/task.yaml | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100644 tests/profiles/toybox/task.yaml diff --git a/.image-garden.mk b/.image-garden.mk index e8286709a..c970152ba 100644 --- a/.image-garden.mk +++ b/.image-garden.mk @@ -31,6 +31,7 @@ packages: - python3-tk - python3-ttkthemes - swig +- toybox endef # Ubuntu shares cloud-init profile with Debian. diff --git a/tests/profiles/toybox/task.yaml b/tests/profiles/toybox/task.yaml new file mode 100644 index 000000000..44e2f6ea1 --- /dev/null +++ b/tests/profiles/toybox/task.yaml @@ -0,0 +1,11 @@ +summary: smoke test for the toybox profile +systems: + # Toybox is not packaged on openSUSE + - -opensuse-* +execute: | + # Toybox works (this is a very basic test). + test "$(toybox id -u)" -eq 0 + # The profile may be used explicitly. + aa-exec -p toybox toybox cat /proc/self/attr/current | MATCH 'toybox \(unconfined\)' + # The profile is attached implicitly based on path name. + toybox cat /proc/self/attr/current | MATCH 'toybox \(unconfined\)'