Package: release.debian.org
Control: affects -1 + src:ceph
User: release.debian....@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: dan...@debian.org

Hi,

this is a pre-approval request to allow uploading and unblocking ceph/18.2.7-3.

It fixes a regression from CVE-2025-52555 where unprivileged users can set setuid or setguid on files:

  * https://bugs.debian.org/1109470

  * https://github.com/ceph/ceph/pull/64356
* https://github.com/ceph/ceph/commit/7028ed21138522495df1e9f8b01195a3c43d47ff.patch

I've prepared an updated package for ceph:

  * https://salsa.debian.org/ceph-team/ceph/-/commits/debian/unstable

I've previously applied the fix on our ceph cluster at work, no issues.

As ceph is a key package, I'm awaiting your feedback to upload it to unstable, diff is attached.

Regards,
Daniel
diff --git a/debian/changelog b/debian/changelog
index 2ac580bfa7..44da762156 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+ceph (18.2.7-3) unstable; urgency=high
+
+  * Adding patch from upstream to fix regression with CVE-2025-52555:
+    - unprivileged users can set S_ISUID and/or S_ISGID bits when changed
+      seperatly from each other (Closes: #1109470).
+
+ -- Daniel Baumann <dan...@debian.org>  Mon, 21 Jul 2025 10:06:16 +0200
+
 ceph (18.2.7-2) unstable; urgency=medium
 
   * Add 0010-ceph-volume-fix-importlib.metadata-compat.patch
diff --git a/debian/patches/0031-CVE-2025-52555-regression.patch b/debian/patches/0031-CVE-2025-52555-regression.patch
new file mode 100644
index 0000000000..d5aebce07d
--- /dev/null
+++ b/debian/patches/0031-CVE-2025-52555-regression.patch
@@ -0,0 +1,101 @@
+Author: Kefu Chai <tchai...@gmail.com>
+Description: [PATCH] client: prohibit unprivileged users from setting sgid/suid bits
+ Prior to fb1b72d, unprivileged users could add mode bits as long as
+ S_ISUID and S_ISGID were not included in the change.
+ .
+ After fb1b72d, unprivileged users were allowed to modify S_ISUID and
+ S_ISGID bits only when no other mode bits were changed in the same
+ operation. This inadvertently permitted unprivileged users to set
+ S_ISUID and/or S_ISGID bits when they were the sole bits being modified.
+ .
+ This behavior should not be allowed. Unprivileged users should be
+ prohibited from setting S_ISUID and/or S_ISGID bits under any
+ circumstances.
+ .
+ This change tightens the permission check to prevent unprivileged
+ users from setting these privileged bits in all cases.
+
+diff -Naurp ceph.orig/src/client/Client.cc ceph/src/client/Client.cc
+--- ceph.orig/src/client/Client.cc
++++ ceph/src/client/Client.cc
+@@ -6031,22 +6031,23 @@ int Client::may_setattr(Inode *in, struc
+   }
+ 
+   if (mask & CEPH_SETATTR_MODE) {
+-    bool allowed = false;
+     /*
+      * Currently the kernel fuse and libfuse code is buggy and
+      * won't pass the ATTR_KILL_SUID/ATTR_KILL_SGID to ceph-fuse.
+      * But will just set the ATTR_MODE and at the same time by
+      * clearing the suid/sgid bits.
+      *
+-     * Only allow unprivileged users to clear S_ISUID and S_ISUID.
++     * Only allow unprivileged users to clear S_ISUID and S_ISGID.
+      */
+-    if ((in->mode & (S_ISUID | S_ISGID)) != (stx->stx_mode & (S_ISUID | S_ISGID)) &&
+-        (in->mode & ~(S_ISUID | S_ISGID)) == (stx->stx_mode & ~(S_ISUID | S_ISGID))) {
+-      allowed = true;
+-    }
+-    uint32_t m = ~stx->stx_mode & in->mode; // mode bits removed
+-    ldout(cct, 20) << __func__ << " " << *in << " = " << hex << m << dec <<  dendl;
+-    if (perms.uid() != 0 && perms.uid() != in->uid && !allowed)
++    uint32_t removed_bits = ~stx->stx_mode & in->mode;
++    uint32_t added_bits = ~in->mode & stx->stx_mode;
++    bool clearing_suid_sgid = (
++      // no new bits added
++      added_bits == 0 &&
++      // only suid/suid bits removed
++      (removed_bits & ~(S_ISUID | S_ISGID)) == 0);
++    ldout(cct, 20) << __func__ << " " << *in << " = " << hex << removed_bits << dec <<  dendl;
++    if (perms.uid() != 0 && perms.uid() != in->uid && !clearing_suid_sgid)
+       goto out;
+ 
+     gid_t i_gid = (mask & CEPH_SETATTR_GID) ? stx->stx_gid : in->gid;
+diff -Naurp ceph.orig/src/test/libcephfs/suidsgid.cc ceph/src/test/libcephfs/suidsgid.cc
+--- ceph.orig/src/test/libcephfs/suidsgid.cc
++++ ceph/src/test/libcephfs/suidsgid.cc
+@@ -19,6 +19,7 @@
+ #include "include/stringify.h"
+ #include "include/cephfs/libcephfs.h"
+ #include "include/rados/librados.h"
++#include <cerrno>
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+@@ -142,6 +143,17 @@ void run_change_mode_test_case()
+   ASSERT_EQ(ceph_chmod(cmount, c_dir, 0777), -CEPHFS_EPERM);
+ }
+ 
++static void run_set_sgid_suid_test_case(int old_suid_sgid,
++					int new_suid_sgid,
++					int expected_result)
++{
++  char c_dir[1024];
++  sprintf(c_dir, "/mode_test_%d", getpid());
++  const int mode = 0766;
++  ASSERT_EQ(ceph_mkdirs(admin, c_dir, mode | old_suid_sgid), 0);
++  ASSERT_EQ(ceph_chmod(cmount, c_dir, mode | new_suid_sgid), expected_result);
++}
++
+ TEST(SuidsgidTest, WriteClearSetuid) {
+   ASSERT_EQ(0, ceph_create(&admin, NULL));
+   ASSERT_EQ(0, ceph_conf_read_file(admin, NULL));
+@@ -214,8 +226,18 @@ TEST(SuidsgidTest, WriteClearSetuid) {
+   // 14, Truncate by unprivileged user clears the suid and sgid
+   run_truncate_test_case(06766, 0, 100);
+ 
++  // 15, Prohibit unpriviledged user from changing non-sgid/suid
++  //     mode bits
+   run_change_mode_test_case();
+ 
++  // 16, Prohibit unpriviledged user from setting suid/sgid
++  run_set_sgid_suid_test_case(0, S_ISUID, -EPERM);
++  run_set_sgid_suid_test_case(0, S_ISGID, -EPERM);
++  run_set_sgid_suid_test_case(0, S_ISUID | S_ISGID, -EPERM);
++  run_set_sgid_suid_test_case(S_ISGID, S_ISUID, -EPERM);
++  run_set_sgid_suid_test_case(S_ISUID, S_ISGID, -EPERM);
++  run_set_sgid_suid_test_case(S_ISGID, S_ISUID | S_ISGID, -EPERM);
++
+   // clean up
+   ceph_shutdown(cmount);
+   ceph_shutdown(admin);
diff --git a/debian/patches/series b/debian/patches/series
index 8d2ed4e4b6..c934e1ce38 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -29,6 +29,7 @@
 0028-cephadm-do-not-write-logrotate.patch
 0029-fix-ftbfs-loongson64.patch
 0030-fix-ftbfs-with-fmt10.patch
+0031-CVE-2025-52555-regression.patch
 py313-compat/0001-mgr-stop-using-deprecated-API-to-initialize-Python.patch
 py313-compat/0002-mgr-set-argv-for-python-in-PyModuleRegistry.patch
 py313-compat/0003-mgr-add-site-package-paths-in-PyModuleRegistry.patch

Reply via email to