1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
summary: Check that snap-device-helper operates correctly
details: |
The test verifies that snap-device-helper correctly modifies the cgroups
systems:
#TODO: bpftool is not available on core22+ and tests.device-cgroup needs it for cgroups v2
- -ubuntu-core-22-*
- -ubuntu-core-24-*
environment:
# note that /dev/full has well known major:minor which is 1:7
DEVICES_PATH_MEM_FULL: /devices/virtual/mem/full
# and /dev/kmsg has 1:11
DEVICES_PATH_MEM_KMSG: /devices/virtual/mem/kmsg
# enable debugs from s-c
SNAPD_DEBUG: "1"
debug: |
udevadm info /dev/full || true
udevadm info /dev/kmsg || true
tests.device-cgroup test-strict-cgroup-helper.sh dump || true
execute: |
#shellcheck source=tests/lib/systems.sh
. "$TESTSLIB/systems.sh"
# In essence we need to use the helper from snap, as it's the only location
# which is now carrying the potentially modified code (since snapd package
# is installed from distribution repos and so it contains older, already merged code).
libexecdir=$(os.paths libexec-dir)
if tests.info is-snapd-from-archive; then
libexecdir="/snap/snapd/current$libexecdir"
fi
echo "Given a snap is installed"
"$TESTSTOOLS"/snaps-state install-local test-strict-cgroup-helper
echo "Verify that no devices are assigned to that snap"
udevadm info "/sys/$DEVICES_PATH_MEM_FULL" | NOMATCH "E: (CURRENT_)?TAGS=.*snap_test-strict-cgroup-helper_sh"
udevadm info "/sys/$DEVICES_PATH_MEM_KMSG" | NOMATCH "E: (CURRENT_)?TAGS=.*snap_test-strict-cgroup-helper_sh"
echo "Force a device cgroup to be assigned to a snap"
# this will assign the /dev/full device to a snap
content='KERNEL=="full", TAG+="snap_test-strict-cgroup-helper_sh" '
echo "$content" > /etc/udev/rules.d/70-snap.test-strict-cgroup-helper.rules
udevadm control --reload-rules
udevadm settle
udevadm trigger
udevadm settle
# /dev/full is now tagged for the snap
udevadm info "/sys/$DEVICES_PATH_MEM_FULL" | MATCH "E: (CURRENT_)?TAGS=.*snap_test-strict-cgroup-helper_sh"
# but /dev/kmsg is not
udevadm info "/sys/$DEVICES_PATH_MEM_KMSG" | NOMATCH "E: (CURRENT_)?TAGS=.*snap_test-strict-cgroup-helper_sh"
# the apparmor profile prevents the app from accessing /dev/kmsg workaround
# it by switching the profile to complain
if aa-status && test -e /var/lib/snapd/apparmor/profiles/snap.test-strict-cgroup-helper.sh; then
sed -i -e 's/attach_disconnected,/attach_disconnected,complain,/' \
/var/lib/snapd/apparmor/profiles/snap.test-strict-cgroup-helper.sh
# ensure the right apparmor_parser is used
APPARMOR_PARSER="apparmor_parser"
if snap debug sandbox-features --required apparmor:parser:snapd-internal; then
APPARMOR_PARSER="/snap/snapd/current/usr/lib/snapd/apparmor_parser --config-file /snap/snapd/current/usr/lib/snapd/apparmor/parser.conf -b /snap/snapd/current/usr/lib/snapd/apparmor.d --policy-features /snap/snapd/current/usr/lib/snapd/apparmor.d/abi/4.0"
fi
$APPARMOR_PARSER -r /var/lib/snapd/apparmor/profiles/snap.test-strict-cgroup-helper.sh
fi
snap run test-strict-cgroup-helper.sh -c 'echo hello'
# explicitly verify that the right cgroup path exists, which is either
# /sys/fs/cgroup/devices/snap.test-strict-cgroup-helper.sh or
# /sys/fs/bpf/snap/test-strict-cgroup-helper_sh
if is_cgroupv2; then
test -e /sys/fs/bpf/snap/snap_test-strict-cgroup-helper_sh
else
test -e /sys/fs/cgroup/devices/snap.test-strict-cgroup-helper.sh
fi
tests.device-cgroup test-strict-cgroup-helper.sh dump | MATCH 'c 1:7 rwm'
# /dev/kmsg is not added
tests.device-cgroup test-strict-cgroup-helper.sh dump | NOMATCH 'c 1:11 rwm'
# and it's not possible to read /dev/kmsg
snap run test-strict-cgroup-helper.sh -c 'head -1 /dev/kmsg' 2>&1 | MATCH "Operation not permitted"
# snap-device-helper is invoked by udev as:
# RUN+="$libexecdir/snapd/snap-device-helper snap_test-strict-cgroup-helper_sh"
ACTION=add MAJOR=1 MINOR=7 SUBSYSTEM=mem "$libexecdir"/snapd/snap-device-helper snap_test-strict-cgroup-helper_sh
ACTION=change MAJOR=1 MINOR=7 SUBSYSTEM=mem "$libexecdir"/snapd/snap-device-helper snap_test-strict-cgroup-helper_sh
# still present
tests.device-cgroup test-strict-cgroup-helper.sh dump | MATCH 'c 1:7 rwm'
# now invoke it for /dev/kmsg, but since the device cgroup is reinitialized
# when the snap starts, we have to make the operation async
rm -f /var/snap/test-strict-cgroup-helper/common/ready
snap run test-strict-cgroup-helper.sh -c 'touch /var/snap/test-strict-cgroup-helper/common/started; until test -e /var/snap/test-strict-cgroup-helper/common/ready; do sleep 1; done; head -1 /dev/kmsg' > run.log 2>&1 &
retry -n 5 test -e /var/snap/test-strict-cgroup-helper/common/started
# device got added
ACTION=add MAJOR=1 MINOR=11 SUBSYSTEM=mem "$libexecdir"/snapd/snap-device-helper snap_test-strict-cgroup-helper_sh
tests.device-cgroup test-strict-cgroup-helper.sh dump | MATCH 'c 1:11 rwm'
# or changed
ACTION=change MAJOR=1 MINOR=11 SUBSYSTEM=mem "$libexecdir"/snapd/snap-device-helper snap_test-strict-cgroup-helper_sh
tests.device-cgroup test-strict-cgroup-helper.sh dump | MATCH 'c 1:11 rwm'
# or bound to driver
ACTION=bind MAJOR=1 MINOR=11 SUBSYSTEM=mem "$libexecdir"/snapd/snap-device-helper snap_test-strict-cgroup-helper_sh
tests.device-cgroup test-strict-cgroup-helper.sh dump | MATCH 'c 1:11 rwm'
# and it should be possible to read a line now
touch /var/snap/test-strict-cgroup-helper/common/ready
# wait for the snap application we started in the background earlier to
# finish
wait
NOMATCH 'Operation not permitted' < run.log
test -n "$(cat run.log)"
# unbind does not remove the device
ACTION=unbind MAJOR=1 MINOR=11 SUBSYSTEM=mem "$libexecdir"/snapd/snap-device-helper snap_test-strict-cgroup-helper_sh
tests.device-cgroup test-strict-cgroup-helper.sh dump | MATCH 'c 1:11 rwm'
# remove action removes the device from the cgroup
ACTION=remove MAJOR=1 MINOR=11 SUBSYSTEM=mem "$libexecdir"/snapd/snap-device-helper snap_test-strict-cgroup-helper_sh
# /dev/kmsg is not present anymore
tests.device-cgroup test-strict-cgroup-helper.sh dump | NOMATCH 'c 1:11 rwm'
# and it's not possible to read /dev/kmsg again
snap run test-strict-cgroup-helper.sh -c 'head -1 /dev/kmsg' 2>&1 | MATCH "Operation not permitted"
# now remove the cgroup
if is_cgroupv2; then
rm /sys/fs/bpf/snap/snap_test-strict-cgroup-helper_sh
else
rmdir /sys/fs/cgroup/devices/snap.test-strict-cgroup-helper.sh
fi
# running the helper does not fail for either device and action
ACTION=add MAJOR=1 MINOR=7 SUBSYSTEM=mem "$libexecdir"/snapd/snap-device-helper snap_test-strict-cgroup-helper_sh
ACTION=change MAJOR=1 MINOR=7 SUBSYSTEM=mem "$libexecdir"/snapd/snap-device-helper snap_test-strict-cgroup-helper_sh
ACTION=add MAJOR=1 MINOR=11 SUBSYSTEM=mem "$libexecdir"/snapd/snap-device-helper snap_test-strict-cgroup-helper_sh
ACTION=change MAJOR=1 MINOR=11 SUBSYSTEM=mem "$libexecdir"/snapd/snap-device-helper snap_test-strict-cgroup-helper_sh
# and the device cgroup map/directory is still gone
if is_cgroupv2; then
test ! -e /sys/fs/bpf/snap/snap_test-strict-cgroup-helper_sh
else
test ! -e /sys/fs/cgroup/devices/snap.test-strict-cgroup-helper.sh
fi
|