[PATCH 2/3] fstests: test restricted symlinks & hardlinks sysctls

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]



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@xxxxxxxxxx>
---

diff --git a/tests/generic/900 b/tests/generic/900
new file mode 100755
index 00000000..f0ac46ef
--- /dev/null
+++ b/tests/generic/900
@@ -0,0 +1,114 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2020 Red Hat, Inc.  All Rights Reserved.
+#
+# FS QA Test 900
+#
+# Test protected_symlink and protected_hardlink ioctls
+#
+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
+	sysctl -qw fs.protected_symlinks=$SYMLINK_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 fs.protected_symlinks
+_require_sysctl fs.protected_hardlinks
+_require_user fsgqa
+_require_user fsgqa2
+
+OWNER=fsgqa
+OTHER=fsgqa2
+
+# 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
+	sudo -u $OTHER cat $TEST_DIR/$seq/sticky_dir/symlink 2>&1 \
+		 | _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
+	sudo -u $OTHER \
+	    ln $TEST_DIR/$seq/target $TEST_DIR/$seq/sticky_dir/hardlink 2>&1 \
+		| _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/900.out b/tests/generic/900.out
new file mode 100644
index 00000000..c9b26dbd
--- /dev/null
+++ b/tests/generic/900.out
@@ -0,0 +1,14 @@
+QA output created by 900
+== Test symlink follow protection when
+== process != link owner and dir owner != link owner
+fs.protected_symlinks = 0
+successfully followed symlink
+fs.protected_symlinks = 1
+cat: TEST_DIR/900/sticky_dir/symlink: 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/900/sticky_dir/hardlink' => 'TEST_DIR/900/target': Operation not permitted
diff --git a/tests/generic/group b/tests/generic/group
index 718575ba..782b0cc3 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -598,3 +598,4 @@
 594 auto quick quota
 595 auto quick encrypt
 596 auto quick
+900 auto quick perms





[Index of Archives]     [Linux Filesystems Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux