Skip to content

Commit

Permalink
tests: extend interfaces-personal-files for missing directory creation (
Browse files Browse the repository at this point in the history
  • Loading branch information
ernestl committed Dec 16, 2023
1 parent e5d50be commit 32cf414
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 7 deletions.
112 changes: 106 additions & 6 deletions tests/main/interfaces-personal-files/task.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"
Expand All @@ -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 </var/lib/snapd/mount/snap.test-snapd-sh.user-fstab)" -eq 1
# shellcheck disable=SC2016
MATCH 'none \$HOME/.missing none x-snapd.kind=ensure-dir,x-snapd.must-exist-dir=\$HOME 0 0' < /var/lib/snapd/mount/snap.test-snapd-sh.user-fstab
echo "Find snap-confine"
SNAP_CONFINE=$(os.paths libexec-dir)/snapd/snap-confine
# on Ubuntu Core we need to use the correct path to ensure it is
# appropriately confined by apparmor as it may be from the snapd
# snap
if os.query is-core16; then
# on uc16, we should just use /usr/lib/snapd/snap-confine from the host
# which by definition will come from the currently installed core snap
SNAP_CONFINE=/usr/lib/snapd/snap-confine
elif os.query is-core; then
# on UC18+, snap-confine will come from the snapd snap, so use the
# active installed revision as the snap-confine to execute
SNAPD_SNAP_REV=$(snap list snapd | tail -n +2 | awk '{print $3}')
SNAP_CONFINE="/snap/snapd/$SNAPD_SNAP_REV/usr/lib/snapd/snap-confine"
fi
# Ubuntu 14.04 does not have busctl required by tests.session
if ! os.query is-ubuntu 14.04; then
echo "Cannot abuse snap-confine to create $TEST_USER_HOME/.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=$TEST_USER_HOME $SNAP_CONFINE snap.test-snapd-sh.with-personal-files-plug /bin/sh -c exit"
if tests.session -u $TEST_USER2 exec sh -c "$cmd" > 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"
Expand All @@ -47,22 +144,22 @@ 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"
if [ "$(snap debug confinement)" = partial ] ; then
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"
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 32cf414

Please sign in to comment.