]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
libcephfs: add test cases for dropping the suid/sgid in write/truncate
authorXiubo Li <xiubli@redhat.com>
Mon, 13 Mar 2023 06:48:34 +0000 (14:48 +0800)
committerXiubo Li <xiubli@redhat.com>
Tue, 11 Apr 2023 02:04:14 +0000 (10:04 +0800)
Write/truncate by privileged user leaves the suid and sgid and by
unprivileged user will clear them.

Fixes: https://tracker.ceph.com/issues/58680
Signed-off-by: Xiubo Li <xiubli@redhat.com>
(cherry picked from commit 8886f5f5dd47fc51688f7cd3096dad43cfcaa249)

src/test/libcephfs/suidsgid.cc
src/test/libcephfs/test.cc

index b90b1d2855d88ebcaafe0da1dfe59b6faa96bfdb..fc7ee38776196c520a899cc390f192d93a9021d2 100644 (file)
@@ -94,6 +94,46 @@ int do_mon_command(string s, string *key)
   return r;
 }
 
+void run_write_test_case(int mode, int result, bool with_admin=false)
+{
+  struct ceph_statx stx;
+
+  ASSERT_EQ(0, ceph_chmod(admin, filename, mode));
+
+  struct ceph_mount_info *_cmount = cmount;
+  if (with_admin) {
+    _cmount = admin;
+  }
+  int fd = ceph_open(_cmount, filename, O_RDWR, 0);
+  ASSERT_LE(0, fd);
+  ASSERT_EQ(ceph_write(_cmount, fd, "foo", 3, 0), 3);
+  ASSERT_EQ(ceph_statx(_cmount, filename, &stx, CEPH_STATX_MODE, 0), 0);
+  std::cout << "After ceph_write, mode: 0" << oct << mode << " -> 0"
+            << (stx.stx_mode & 07777) << dec << std::endl;
+  ASSERT_EQ(stx.stx_mode & (S_ISUID|S_ISGID), result);
+  ceph_close(_cmount, fd);
+}
+
+void run_truncate_test_case(int mode, int result, size_t size, bool with_admin=false)
+{
+  struct ceph_statx stx;
+
+  ASSERT_EQ(0, ceph_chmod(admin, filename, mode));
+
+  struct ceph_mount_info *_cmount = cmount;
+  if (with_admin) {
+    _cmount = admin;
+  }
+  int fd = ceph_open(_cmount, filename, O_RDWR, 0);
+  ASSERT_LE(0, fd);
+  ASSERT_GE(ceph_ftruncate(_cmount, fd, size), 0);
+  ASSERT_EQ(ceph_statx(_cmount, filename, &stx, CEPH_STATX_MODE, 0), 0);
+  std::cout << "After ceph_truncate size " << size << " mode: 0" << oct
+            << mode << " -> 0" << (stx.stx_mode & 07777) << dec << std::endl;
+  ASSERT_EQ(stx.stx_mode & (S_ISUID|S_ISGID), result);
+  ceph_close(_cmount, fd);
+}
+
 TEST(SuidsgidTest, WriteClearSetuid) {
   ASSERT_EQ(0, ceph_create(&admin, NULL));
   ASSERT_EQ(0, ceph_conf_read_file(admin, NULL));
@@ -154,6 +194,18 @@ TEST(SuidsgidTest, WriteClearSetuid) {
   // 10, Commit to a all-exec file by an unprivileged user clears sgid.
   run_fallocate_test_case(02777, 0); // a+rwx,g+rwxs
 
+  // 11, Write by privileged user leaves the suid and sgid
+  run_write_test_case(06766, S_ISUID | S_ISGID, true);
+
+  // 12, Write by unprivileged user clears the suid and sgid
+  run_write_test_case(06766, 0);
+
+  // 13, Truncate by privileged user leaves the suid and sgid
+  run_truncate_test_case(06766, S_ISUID | S_ISGID, 10000, true);
+
+  // 14, Truncate by unprivileged user clears the suid and sgid
+  run_truncate_test_case(06766, 0, 100);
+
   // clean up
   ceph_shutdown(cmount);
   ceph_shutdown(admin);
index acaa15a9758a2af9adb40227e0a499cf8e48395b..42563166052c319f787dcbfd1d3e2a01ca213de3 100644 (file)
@@ -2070,33 +2070,6 @@ TEST(LibCephFS, ClearSetuid) {
 
   ASSERT_EQ(stx.stx_mode & (mode_t)ALLPERMS, before_mode);
 
-  // write
-  ASSERT_EQ(ceph_ll_write(cmount, fh, 0, 3, "foo"), 3);
-  ASSERT_EQ(ceph_ll_getattr(cmount, in, &stx, CEPH_STATX_MODE, 0, usercred), 0);
-  ASSERT_TRUE(stx.stx_mask & CEPH_STATX_MODE);
-  ASSERT_EQ(stx.stx_mode & (mode_t)ALLPERMS, after_mode);
-
-  // reset mode
-  stx.stx_mode = before_mode;
-  ASSERT_EQ(ceph_ll_setattr(cmount, in, &stx, CEPH_STATX_MODE, usercred), 0);
-  ASSERT_EQ(ceph_ll_getattr(cmount, in, &stx, CEPH_STATX_MODE, 0, usercred), 0);
-  ASSERT_TRUE(stx.stx_mask & CEPH_STATX_MODE);
-  ASSERT_EQ(stx.stx_mode & (mode_t)ALLPERMS, before_mode);
-
-  // truncate
-  stx.stx_size = 1;
-  ASSERT_EQ(ceph_ll_setattr(cmount, in, &stx, CEPH_SETATTR_SIZE, usercred), 0);
-  ASSERT_EQ(ceph_ll_getattr(cmount, in, &stx, CEPH_STATX_MODE, 0, usercred), 0);
-  ASSERT_TRUE(stx.stx_mask & CEPH_STATX_MODE);
-  ASSERT_EQ(stx.stx_mode & (mode_t)ALLPERMS, after_mode);
-
-  // reset mode
-  stx.stx_mode = before_mode;
-  ASSERT_EQ(ceph_ll_setattr(cmount, in, &stx, CEPH_STATX_MODE, usercred), 0);
-  ASSERT_EQ(ceph_ll_getattr(cmount, in, &stx, CEPH_STATX_MODE, 0, usercred), 0);
-  ASSERT_TRUE(stx.stx_mask & CEPH_STATX_MODE);
-  ASSERT_EQ(stx.stx_mode & (mode_t)ALLPERMS, before_mode);
-
   // chown  -- for this we need to be "root"
   UserPerm *rootcred = ceph_userperm_new(0, 0, 0, NULL);
   ASSERT_TRUE(rootcred);