CVE-2022-3650: ceph-crash: drop privleges to run as "ceph" user, rather than root
authorTim Serong <tserong@suse.com>
Wed, 2 Nov 2022 03:27:47 +0000 (14:27 +1100)
committerThomas Goirand <zigo@debian.org>
Thu, 16 Feb 2023 10:54:41 +0000 (10:54 +0000)
Bug: https://tracker.ceph.com/issues/57967
Signed-off-by: Tim Serong <tserong@suse.com>
Origin: upstream, https://github.com/ceph/ceph/commit/130c9626598bc3a75942161e6cce7c664c447382
Bug-Debian: https://bugs.debian.org/1024932
Last-Update: 2022-11-28

If privileges cannot be dropped, log an error and exit.  This commit
also catches and logs exceptions when scraping the crash path, without
which ceph-crash would just exit if it encountered an error.

Gbp-Pq: Name CVE-2022-3650_1_ceph-crash_drop_privleges_to_run_as_ceph_user_rather_than_root.patch

src/ceph-crash.in

index ae0e4f516464fd4d63a96d497cfe3d7545f89eda..18d3191d7e1db1aa79b0fdb74467a695566f53cb 100755 (executable)
@@ -3,8 +3,10 @@
 # vim: ts=4 sw=4 smarttab expandtab
 
 import argparse
+import grp
 import logging
 import os
+import pwd
 import signal
 import socket
 import subprocess
@@ -83,8 +85,25 @@ def handler(signum):
     print('*** Interrupted with signal %d ***' % signum)
     sys.exit(0)
 
+def drop_privs():
+    if os.getuid() == 0:
+        try:
+            ceph_uid = pwd.getpwnam("ceph").pw_uid
+            ceph_gid = grp.getgrnam("ceph").gr_gid
+            os.setgroups([])
+            os.setgid(ceph_gid)
+            os.setuid(ceph_uid)
+        except Exception as e:
+            log.error(f"Unable to drop privileges: {e}")
+            sys.exit(1)
+
+
 def main():
     global auth_names
+
+    # run as unprivileged ceph user
+    drop_privs()
+
     # exit code 0 on SIGINT, SIGTERM
     signal.signal(signal.SIGINT, handler)
     signal.signal(signal.SIGTERM, handler)
@@ -103,7 +122,10 @@ def main():
 
     log.info("monitoring path %s, delay %ds" % (args.path, args.delay * 60.0))
     while True:
-        scrape_path(args.path)
+        try:
+            scrape_path(args.path)
+        except Exception as e:
+            log.error(f"Error scraping {args.path}: {e}")
         if args.delay == 0:
             sys.exit(0)
         time.sleep(args.delay * 60)