Thread (13 messages) flat view 13 messages, 3 authors, 2023-08-25
STALE1077d

[PATCH 1/3] selftests/mount_setattr: Add a test to test locking mount attrs

From: Sargun Dhillon <hidden>
Date: 2023-08-10 09:00:50
Also in: linux-fsdevel
Subsystem: filesystems [idmapped mounts], kernel selftest framework, the rest · Maintainers: Christian Brauner, Seth Forshee, Shuah Khan, Shuah Khan, Linus Torvalds

Certain mount attributes are meant to be locked when sharing mounts with
another mount namespace. This validates that behaviour holds as expected.

 - Locked attributes are not changeable
 - Non-locked attributes can be changed, and changed back

Test output:
  sudo ./mount_setattr_test  -t mount_attr_lock
  make: Nothing to be done for 'all'.
  TAP version 13
  1..1
  # Starting 1 tests from 1 test cases.
  #  RUN           mount_setattr.mount_attr_lock ...
  #            OK  mount_setattr.mount_attr_lock
  ok 1 mount_setattr.mount_attr_lock
  # PASSED: 1 / 1 tests passed.
  # Totals: pass:1 fail:0 xfail:0 xpass:0 skip:0 error:0

Signed-off-by: Sargun Dhillon <redacted>
---
 .../mount_setattr/mount_setattr_test.c        | 54 +++++++++++++++++++
 1 file changed, 54 insertions(+)
diff --git a/tools/testing/selftests/mount_setattr/mount_setattr_test.c b/tools/testing/selftests/mount_setattr/mount_setattr_test.c
index c6a8c732b802..2aaa4aae41f5 100644
--- a/tools/testing/selftests/mount_setattr/mount_setattr_test.c
+++ b/tools/testing/selftests/mount_setattr/mount_setattr_test.c
@@ -400,6 +400,11 @@ FIXTURE_SETUP(mount_setattr)
 	ASSERT_EQ(mount("testing", "/tmp/B/BB", "tmpfs", MS_NOATIME | MS_NODEV,
 			"size=100000,mode=700"), 0);
 
+	ASSERT_EQ(mkdir("/tmp/C", 0777), 0);
+
+	ASSERT_EQ(mount("testing", "/tmp/C", "tmpfs", MS_NOATIME,
+			"size=100000,mode=700"), 0);
+
 	ASSERT_EQ(mount("testing", "/mnt", "tmpfs", MS_NOATIME | MS_NODEV,
 			"size=100000,mode=700"), 0);
 
@@ -1497,4 +1502,53 @@ TEST_F(mount_setattr, mount_attr_nosymfollow)
 	ASSERT_EQ(close(fd), 0);
 }
 
+TEST_F(mount_setattr, mount_attr_lock)
+{
+	struct mount_attr attr = {
+		.attr_set = MOUNT_ATTR_RDONLY|MOUNT_ATTR_NOSUID|MOUNT_ATTR_NODEV,
+	};
+
+	ASSERT_EQ(sys_mount_setattr(-1, "/tmp/C", 0, &attr, sizeof(attr)), 0);
+	ASSERT_EQ(prepare_unpriv_mountns(), 0);
+
+	attr.attr_set = 0;
+	attr.attr_clr = MOUNT_ATTR_RDONLY;
+	ASSERT_EQ(sys_mount_setattr(-1, "/tmp/C", 0, &attr, sizeof(attr)), -1);
+	ASSERT_EQ(errno, EPERM);
+
+	attr.attr_clr = MOUNT_ATTR_NOSUID;
+	ASSERT_EQ(sys_mount_setattr(-1, "/tmp/C", 0, &attr, sizeof(attr)), -1);
+	ASSERT_EQ(errno, EPERM);
+
+	attr.attr_clr = MOUNT_ATTR_NODEV;
+	ASSERT_EQ(sys_mount_setattr(-1, "/tmp/C", 0, &attr, sizeof(attr)), -1);
+	ASSERT_EQ(errno, EPERM);
+
+	/* Do not allow changing any atime flags after locking */
+	attr.attr_set = MOUNT_ATTR_RELATIME;
+	attr.attr_clr = MOUNT_ATTR__ATIME;
+	ASSERT_EQ(sys_mount_setattr(-1, "/tmp/C", 0, &attr, sizeof(attr)), -1);
+	ASSERT_EQ(errno, EPERM);
+
+	attr.attr_set = MOUNT_ATTR_STRICTATIME;
+	ASSERT_EQ(sys_mount_setattr(-1, "/tmp/C", 0, &attr, sizeof(attr)), -1);
+	ASSERT_EQ(errno, EPERM);
+
+	attr.attr_set = MOUNT_ATTR_NODIRATIME;
+	ASSERT_EQ(sys_mount_setattr(-1, "/tmp/C", 0, &attr, sizeof(attr)), -1);
+	ASSERT_EQ(errno, EPERM);
+
+	/*
+	 * "re-setting" the atime setting to the same value should work.
+	 * Also, to make sure this isn't a no-op, try making things less permissive
+	 */
+	attr.attr_set = MOUNT_ATTR_NOATIME | MOUNT_ATTR_NOEXEC;
+	ASSERT_EQ(sys_mount_setattr(-1, "/tmp/C", 0, &attr, sizeof(attr)), 0);
+
+	/* We should still be allowed to clear the attribute we set */
+	attr.attr_set = 0;
+	attr.attr_clr = MOUNT_ATTR_NOEXEC;
+	ASSERT_EQ(sys_mount_setattr(-1, "/tmp/C", 0, &attr, sizeof(attr)), 0);
+}
+
 TEST_HARNESS_MAIN
-- 
2.39.3
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help