From: Xiubo Li Date: Mon, 13 Mar 2023 06:48:34 +0000 (+0800) Subject: libcephfs: add test cases for dropping the suid/sgid in write/truncate X-Git-Tag: v18.1.2~8^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=276619677da71785a6e899b014c37127cfba05d5;p=ceph.git libcephfs: add test cases for dropping the suid/sgid in write/truncate 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 (cherry picked from commit 8886f5f5dd47fc51688f7cd3096dad43cfcaa249) --- diff --git a/src/test/libcephfs/suidsgid.cc b/src/test/libcephfs/suidsgid.cc index b90b1d2855d8..fc7ee3877619 100644 --- a/src/test/libcephfs/suidsgid.cc +++ b/src/test/libcephfs/suidsgid.cc @@ -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); diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index acaa15a9758a..42563166052c 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -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);