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