]> git.apps.os.sepia.ceph.com Git - xfstests-dev.git/commitdiff
fstests: test restricted symlinks & hardlinks sysctls
authorEric Sandeen <sandeen@redhat.com>
Mon, 18 May 2020 16:14:43 +0000 (11:14 -0500)
committerEryu Guan <guaneryu@gmail.com>
Sun, 24 May 2020 15:09:42 +0000 (23:09 +0800)
This tests the fs.protected_symlinks and fs.protected_hardlinks
sysctls which restrict links behavior in sticky world-writable
directories as documented in the kernel at
Documentation/admin-guide/sysctl/fs.rst

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Zorro Lang <zlang@redhat.com>
Signed-off-by: Eryu Guan <guaneryu@gmail.com>
tests/generic/597 [new file with mode: 0755]
tests/generic/597.out [new file with mode: 0644]
tests/generic/group

diff --git a/tests/generic/597 b/tests/generic/597
new file mode 100755 (executable)
index 0000000..1d87a23
--- /dev/null
@@ -0,0 +1,117 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2020 Red Hat, Inc.  All Rights Reserved.
+#
+# FS QA Test No. 597
+#
+# Test protected_symlink and protected_hardlink sysctls
+#
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1       # failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+       rm -rf $TEST_DIR/$seq
+       [ ! -z "$SYMLINK_PROTECTION" ] \
+               && sysctl -qw fs.protected_symlinks=$SYMLINK_PROTECTION
+       [ ! -z "$HARDLINK_PROTECTION" ] \
+               && sysctl -qw fs.protected_hardlinks=$HARDLINK_PROTECTION
+       cd /
+       rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+
+# remove previous $seqres.full before test
+rm -f $seqres.full
+
+# real QA test starts here
+
+# Modify as appropriate.
+_supported_fs generic
+_supported_os Linux
+_require_test
+_require_sysctl_variable fs.protected_symlinks
+_require_sysctl_variable fs.protected_hardlinks
+# su in _require_user prints warnings about user name starts with a digit,
+# discard the warning
+_require_user 123456-fsgqa >/dev/null 2>&1
+# Do this SECOND so that qa_user is fsgqa, and _user_do uses that account
+_require_user fsgqa
+
+OWNER=123456-fsgqa
+OTHER=fsgqa
+
+# Save current system state to reset when done
+SYMLINK_PROTECTION=`sysctl -n fs.protected_symlinks`
+HARDLINK_PROTECTION=`sysctl -n fs.protected_hardlinks`
+
+test_symlink()
+{
+       ln -s $TEST_DIR/$seq/target $TEST_DIR/$seq/sticky_dir/symlink
+       chown $OTHER.$OTHER $TEST_DIR/$seq/sticky_dir
+       chown $OWNER.$OWNER $TEST_DIR/$seq/sticky_dir/symlink
+       # If we can read the target, we followed the link
+       _user_do "cat $TEST_DIR/$seq/sticky_dir/symlink" | _filter_test_dir
+       rm -f $TEST_DIR/$seq/sticky_dir/symlink
+}
+
+test_hardlink()
+{
+       chown $OWNER.$OWNER $TEST_DIR/$seq/target
+       chmod go-rw $TEST_DIR/$seq/target
+       _user_do "ln $TEST_DIR/$seq/target $TEST_DIR/$seq/sticky_dir/hardlink" \
+               | _filter_test_dir
+       test -f $TEST_DIR/$seq/sticky_dir/hardlink \
+               && echo "successfully created hardlink"
+       rm -f $TEST_DIR/$seq/sticky_dir/hardlink
+}
+
+setup_tree()
+{
+       # Create world-writable sticky dir
+       mkdir -p $TEST_DIR/$seq/sticky_dir
+       chmod 1777 $TEST_DIR/$seq/sticky_dir
+       # And a file elsewhere that will be linked to from that sticky dir
+       mkdir -p $TEST_DIR/$seq
+       # If we can read it, we followed the link.
+       echo "successfully followed symlink" > $TEST_DIR/$seq/target
+}
+
+setup_tree
+
+# First test fs.protected_symlinks
+# With protection on, symlink follows should fail if the
+# link owner != the sticky directory owner, and the process
+# is not the link owner.
+echo "== Test symlink follow protection when"
+echo "== process != link owner and dir owner != link owner"
+sysctl -w fs.protected_symlinks=0
+test_symlink
+sysctl -w fs.protected_symlinks=1
+test_symlink
+
+echo
+
+# Now test fs.protected_hardlinks
+# With protection on, hardlink creation should fail if the
+# process does not own the target file, and the process does not have
+# read-write access to the target
+echo "== Test hardlink create protection when"
+echo "== process != target owner and process cannot read target"
+sysctl -w fs.protected_hardlinks=0
+test_hardlink
+sysctl -w fs.protected_hardlinks=1
+test_hardlink
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/597.out b/tests/generic/597.out
new file mode 100644 (file)
index 0000000..c654da7
--- /dev/null
@@ -0,0 +1,14 @@
+QA output created by 597
+== Test symlink follow protection when
+== process != link owner and dir owner != link owner
+fs.protected_symlinks = 0
+successfully followed symlink
+fs.protected_symlinks = 1
+Permission denied
+
+== Test hardlink create protection when
+== process != target owner and process cannot read target
+fs.protected_hardlinks = 0
+successfully created hardlink
+fs.protected_hardlinks = 1
+ln: failed to create hard link 'TEST_DIR/597/sticky_dir/hardlink' => 'TEST_DIR/597/target': Operation not permitted
index e82004e87e019e69ea83ae239098c3e96a294d94..db7d936e864256ef90a9b727ba5947f1a9091b5e 100644 (file)
 594 auto quick quota
 595 auto quick encrypt
 596 auto quick
+597 auto quick perms