From 32cf414c7525f168350c18b179294fa2e6573079 Mon Sep 17 00:00:00 2001 From: Ernest Lotter Date: Sat, 16 Dec 2023 21:49:10 +0200 Subject: [PATCH] tests: extend interfaces-personal-files for missing directory creation (#13404) --- .../main/interfaces-personal-files/task.yaml | 112 +++++++++++++++++- .../test-snapd-sh/meta/snap.yaml | 2 +- 2 files changed, 107 insertions(+), 7 deletions(-) diff --git a/tests/main/interfaces-personal-files/task.yaml b/tests/main/interfaces-personal-files/task.yaml index 025eaff0184..7c2ab4dfb9c 100644 --- a/tests/main/interfaces-personal-files/task.yaml +++ b/tests/main/interfaces-personal-files/task.yaml @@ -2,11 +2,20 @@ summary: Ensure that the personal-files interface works. details: | The personal-files interface allows access specific personal files or directories. + Missing parent directories of write paths are created when a snap application is run + by a non-root user. + +environment: + TEST_USER_HOME: /home/test + TEST_USER2: test2 + TEST_USER2_HOME: /home/test2 + TEST_USER3: test3 + ROOT_OWNED_DIR: /etc prepare: | "$TESTSTOOLS"/snaps-state install-local test-snapd-sh - # Fist layer of dirs and files + # First layer of dirs and files "$TESTSTOOLS"/fs-state mock-file /root/.testfile1 "$TESTSTOOLS"/fs-state mock-file /root/testfile1 "$TESTSTOOLS"/fs-state mock-dir /root/.testdir1 @@ -24,12 +33,43 @@ prepare: | "$TESTSTOOLS"/fs-state mock-file /var/tmp/root/testfile2 "$TESTSTOOLS"/fs-state mock-file /var/tmp/root/.testfile2 + # Ubuntu 14.04 does not have busctl required by tests.session + if ! os.query is-ubuntu 14.04; then + # Create additional users. + tests.session -u test prepare + if ! useradd -m -d "$TEST_USER2_HOME" "$TEST_USER2"; then + # Ubuntu Core requires using extrausers db + useradd --extrausers -m -d "$TEST_USER2_HOME" "$TEST_USER2" + fi + tests.session -u "$TEST_USER2" prepare + if ! useradd -M "$TEST_USER3"; then + useradd --extrausers -M "$TEST_USER3" + fi + tests.session -u "$TEST_USER3" prepare + fi + restore: | + if ! os.query is-ubuntu 14.04; then + tests.session -u test restore + tests.session -u "$TEST_USER2" restore + tests.session -u "$TEST_USER3" restore + if ! userdel -rf "$TEST_USER2"; then + userdel --extrausers -rf "$TEST_USER2" + fi + if ! userdel -rf "$TEST_USER3"; then + userdel --extrausers -rf "$TEST_USER3" + fi + fi + "$TESTSTOOLS"/fs-state restore-file /root/.testfile1 "$TESTSTOOLS"/fs-state restore-file /root/testfile1 "$TESTSTOOLS"/fs-state restore-dir /root/.testdir1 "$TESTSTOOLS"/fs-state restore-dir /root/testdir1 + "$TESTSTOOLS"/fs-state restore-dir /var/tmp/.testdir1 + "$TESTSTOOLS"/fs-state restore-file /var/tmp/.testfile1 "$TESTSTOOLS"/fs-state restore-dir /var/tmp/root + rm -rf "$TEST_USER_HOME/.testdir1" + rm -rf "$TEST_USER_HOME/.missing/testdir1" execute: | echo "The interface is not connected by default" @@ -38,7 +78,64 @@ execute: | echo "When the interface is connected" snap connect test-snapd-sh:personal-files - echo "Then the snap is able to access all the files and dirs in $HOME" + echo "There is a single \"ensure-dir\" kind of user mount entry for \$HOME/.local/share" + test -e /var/lib/snapd/mount/snap.test-snapd-sh.user-fstab + test "$(wc -l call.error 2>&1; then + echo 'Expected error: "snap-update-ns failed with code 1"' + exit 1 + fi + # shellcheck disable=SC2016 + MATCH 'cannot update snap namespace: cannot expand mount entry \(none \$HOME/.missing none x-snapd.kind=ensure-dir,x-snapd.must-exist-dir=\$HOME 0 0\): cannot use invalid home directory '"\"$TEST_USER_HOME\": permission denied" < call.error + MATCH "snap-update-ns failed with code 1" < call.error + + echo "Cannot abuse snap-confine to create $ROOT_OWNED_DIR/.missing owned by user $TEST_USER2" + # This command is based on what snap run contructs for running a non-classic app with non-root user without the final snap-exec stage + cmd="SNAP_INSTANCE_NAME=test-snapd-sh SNAP_REVISION=x1 SNAP_REAL_HOME=$ROOT_OWNED_DIR $SNAP_CONFINE snap.test-snapd-sh.with-personal-files-plug /bin/sh -c exit" + tests.session -u $TEST_USER2 exec sh -c "$cmd" 2> call.error + prefix="cannot change mount namespace according to change mount \(none $ROOT_OWNED_DIR/.missing none x-snapd.kind=ensure-dir,x-snapd.must-exist-dir=$ROOT_OWNED_DIR 0 0\)" + MATCH "$prefix: cannot create directory \"$ROOT_OWNED_DIR/.missing\": permission denied" < call.error || \ + MATCH "$prefix: cannot operate on read-only filesystem at $ROOT_OWNED_DIR" < call.error + + echo "The snap run as user $TEST_USER3 without a home directory will error" + if tests.session -u "$TEST_USER3" exec test-snapd-sh.with-personal-files-plug -c "exit" > call.error 2>&1; then + echo 'Expected error: "snap-update-ns failed with code 1"' + exit 1 + fi + # shellcheck disable=SC2016 + MATCH 'cannot update snap namespace: cannot expand mount entry \(none \$HOME/.missing none x-snapd.kind=ensure-dir,x-snapd.must-exist-dir=\$HOME 0 0\): cannot use invalid home directory '"\"/home/$TEST_USER3\": no such file or directory" < call.error + MATCH "snap-update-ns failed with code 1" < call.error + + echo "The snap run as user test can create /home/test/testdir and /home/test/.missing/testdir1" + tests.session -u test exec test-snapd-sh.with-personal-files-plug -c "mkdir -p $TEST_USER_HOME/.testdir1" + tests.session -u test exec test-snapd-sh.with-personal-files-plug -c "mkdir -p $TEST_USER_HOME/.missing/testdir1" + fi + + echo "The snap is able to access all the files and dirs in $HOME" test-snapd-sh.with-personal-files-plug -c "cat /root/.testfile1" | MATCH "mock file" test-snapd-sh.with-personal-files-plug -c "cat /root/testfile1" | MATCH "mock file" test-snapd-sh.with-personal-files-plug -c "ls /root/.testdir1" @@ -47,7 +144,7 @@ execute: | test-snapd-sh.with-personal-files-plug -c "cat '/root/.testdir1/test file2'" | MATCH "mock file" test-snapd-sh.with-personal-files-plug -c "ls /root/.testdir1/.testdir2/" - echo "Then the snap is able to write on /root/.testdir1 and /root/.testfile1" + echo "The snap is able to write on /root/.testdir1 and /root/.testfile1" test-snapd-sh.with-personal-files-plug -c "echo test >> /root/.testfile1" test-snapd-sh.with-personal-files-plug -c "touch /root/.testdir1/testfile2" @@ -55,14 +152,14 @@ execute: | exit 0 fi - echo "Then the snap is no able to write outside /root/.testdir1 and /root/.testfile1" + echo "The snap is not able to write outside /root/.testdir1 and /root/.testfile1" if test-snapd-sh.with-personal-files-plug -c "echo test >> /root/testfile1" 2> call.error; then echo "Expected permission error writing the personal file" exit 1 fi MATCH "Permission denied" < call.error - echo "Then the snap is not able to to access files and dirs outside $HOME" + echo "The snap is not able to to access files and dirs outside $HOME" test-snapd-sh.with-personal-files-plug -c "ls /var/tmp/.testdir1" 2>&1| MATCH "Permission denied" test-snapd-sh.with-personal-files-plug -c "cat /var/tmp/.testfile1" 2>&1| MATCH "Permission denied" test-snapd-sh.with-personal-files-plug -c "ls /var/tmp/root/" 2>&1| MATCH "Permission denied" @@ -72,7 +169,10 @@ execute: | echo "When the plug is disconnected" snap disconnect test-snapd-sh:personal-files - echo "Then the snap is not able to read files and dirs in $HOME" + echo "There are no user mount entries" + test ! -e /var/lib/snapd/mount/snap.test-snapd-sh.user-fstab + + echo "The snap is not able to read files and dirs in $HOME" if test-snapd-sh.with-personal-files-plug -c "ls /root/.testdir1" 2> call.error; then echo "Expected permission error accessing the personal dir" exit 1 diff --git a/tests/main/interfaces-personal-files/test-snapd-sh/meta/snap.yaml b/tests/main/interfaces-personal-files/test-snapd-sh/meta/snap.yaml index 796c0f0d27e..efd65d23d30 100644 --- a/tests/main/interfaces-personal-files/test-snapd-sh/meta/snap.yaml +++ b/tests/main/interfaces-personal-files/test-snapd-sh/meta/snap.yaml @@ -5,7 +5,7 @@ version: 1.0 plugs: personal-files: read: [$HOME/.testdir1, $HOME/.testfile1, $HOME/testfile1, $HOME/testdir1] - write: [$HOME/.testdir1, $HOME/.testfile1] + write: [$HOME/.testdir1, $HOME/.testfile1, $HOME/.missing/testdir1] apps: with-personal-files-plug: