|
| 1 | +From e6f1f52409c52c3fd9434015a04065c89d762a21 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Guillaume Abrioux <gabrioux@redhat.com> |
| 3 | +Date: Thu, 24 Feb 2022 17:39:10 +0100 |
| 4 | +Subject: [PATCH 1/6] Revert "src/ceph-crash.in: remove unused frame in |
| 5 | + handler()" |
| 6 | + |
| 7 | +This reverts commit 432c766a99f70884049bf7a1f268287a5a809777. |
| 8 | + |
| 9 | +unused but required: |
| 10 | + |
| 11 | +``` |
| 12 | +Traceback (most recent call last): |
| 13 | +File "/usr/bin/ceph-crash", line 102, in <module> |
| 14 | +main() |
| 15 | +File "/usr/bin/ceph-crash", line 98, in main |
| 16 | +time.sleep(args.delay * 60) |
| 17 | +TypeError: handler() takes exactly 1 argument (2 given) |
| 18 | +``` |
| 19 | + |
| 20 | +Fixes: https://tracker.ceph.com/issues/54422 |
| 21 | + |
| 22 | +Signed-off-by: Guillaume Abrioux <gabrioux@redhat.com> |
| 23 | +Signed-off-by-: Henry Beberman <henry.beberman@microsoft.com> |
| 24 | +(cherry picked from commit 02e8e7d6e6d31b4735115f7820e015fc54997d9f) |
| 25 | +--- |
| 26 | + src/ceph-crash.in | 2 +- |
| 27 | + 1 file changed, 1 insertion(+), 1 deletion(-) |
| 28 | + |
| 29 | +diff --git a/src/ceph-crash.in b/src/ceph-crash.in |
| 30 | +index ae0e4f516464f..4502618fcf7aa 100755 |
| 31 | +--- a/src/ceph-crash.in |
| 32 | ++++ b/src/ceph-crash.in |
| 33 | +@@ -79,7 +79,7 @@ def scrape_path(path): |
| 34 | + (metapath, p, os.path.join('posted/', p)) |
| 35 | + ) |
| 36 | + |
| 37 | +-def handler(signum): |
| 38 | ++def handler(signum, frame): |
| 39 | + print('*** Interrupted with signal %d ***' % signum) |
| 40 | + sys.exit(0) |
| 41 | + |
| 42 | + |
| 43 | +From 50d16ef5e4be857ddc2dcad1bed190c725efef1f Mon Sep 17 00:00:00 2001 |
| 44 | +From: Guillaume Abrioux <gabrioux@redhat.com> |
| 45 | +Date: Thu, 24 Feb 2022 17:45:41 +0100 |
| 46 | +Subject: [PATCH 2/6] ceph-crash: fix some flake8 issues |
| 47 | + |
| 48 | +ceph-crash.in:21:1: E302 expected 2 blank lines, found 1 |
| 49 | +ceph-crash.in:32:80: E501 line too long (86 > 79 characters) |
| 50 | +ceph-crash.in:82:1: E302 expected 2 blank lines, found 1 |
| 51 | +ceph-crash.in:86:1: E302 expected 2 blank lines, found 1 |
| 52 | + |
| 53 | +Signed-off-by: Guillaume Abrioux <gabrioux@redhat.com> |
| 54 | +(cherry picked from commit 0aee76965f92865d7f6e28b73b46dbdb5f1f9463) |
| 55 | +--- |
| 56 | + src/ceph-crash.in | 6 +++++- |
| 57 | + 1 file changed, 5 insertions(+), 1 deletion(-) |
| 58 | + |
| 59 | +diff --git a/src/ceph-crash.in b/src/ceph-crash.in |
| 60 | +index 4502618fcf7aa..916f0664a9456 100755 |
| 61 | +--- a/src/ceph-crash.in |
| 62 | ++++ b/src/ceph-crash.in |
| 63 | +@@ -18,6 +18,7 @@ auth_names = ['client.crash.%s' % socket.gethostname(), |
| 64 | + 'client.crash', |
| 65 | + 'client.admin'] |
| 66 | + |
| 67 | ++ |
| 68 | + def parse_args(): |
| 69 | + parser = argparse.ArgumentParser() |
| 70 | + parser.add_argument( |
| 71 | +@@ -29,7 +30,8 @@ def parse_args(): |
| 72 | + ) |
| 73 | + parser.add_argument( |
| 74 | + '--name', '-n', |
| 75 | +- help='ceph name to authenticate as (default: try client.crash, client.admin)') |
| 76 | ++ help='ceph name to authenticate as ' |
| 77 | ++ '(default: try client.crash, client.admin)') |
| 78 | + parser.add_argument( |
| 79 | + '--log-level', '-l', |
| 80 | + help='log level output (default: INFO), support INFO or DEBUG') |
| 81 | +@@ -79,10 +81,12 @@ def scrape_path(path): |
| 82 | + (metapath, p, os.path.join('posted/', p)) |
| 83 | + ) |
| 84 | + |
| 85 | ++ |
| 86 | + def handler(signum, frame): |
| 87 | + print('*** Interrupted with signal %d ***' % signum) |
| 88 | + sys.exit(0) |
| 89 | + |
| 90 | ++ |
| 91 | + def main(): |
| 92 | + global auth_names |
| 93 | + # exit code 0 on SIGINT, SIGTERM |
| 94 | + |
| 95 | +From 544f5035a6c7880756149c59a8f1b793d1dfd14b Mon Sep 17 00:00:00 2001 |
| 96 | +From: Tim Serong <tserong@suse.com> |
| 97 | +Date: Wed, 2 Nov 2022 14:23:20 +1100 |
| 98 | +Subject: [PATCH 3/6] ceph-crash: fix stderr handling |
| 99 | + |
| 100 | +Popen.communicate() returns a tuple (stdout, stderr), and stderr |
| 101 | +will be of type bytes, hence the need to decode it before checking |
| 102 | +if it's an empty string or not. |
| 103 | + |
| 104 | +Fixes: a77b47eeeb5770eeefcf4619ab2105ee7a6a003e |
| 105 | +Signed-off-by: Tim Serong <tserong@suse.com> |
| 106 | +(cherry picked from commit 45915540559126a652f8d9d105723584cfc63439) |
| 107 | +--- |
| 108 | + src/ceph-crash.in | 3 ++- |
| 109 | + 1 file changed, 2 insertions(+), 1 deletion(-) |
| 110 | + |
| 111 | +diff --git a/src/ceph-crash.in b/src/ceph-crash.in |
| 112 | +index 916f0664a9456..453efb7aa10d0 100755 |
| 113 | +--- a/src/ceph-crash.in |
| 114 | ++++ b/src/ceph-crash.in |
| 115 | +@@ -50,7 +50,8 @@ def post_crash(path): |
| 116 | + stderr=subprocess.PIPE, |
| 117 | + ) |
| 118 | + f = open(os.path.join(path, 'meta'), 'rb') |
| 119 | +- stderr = pr.communicate(input=f.read()) |
| 120 | ++ (_, stderr) = pr.communicate(input=f.read()) |
| 121 | ++ stderr = stderr.decode() |
| 122 | + rc = pr.wait() |
| 123 | + f.close() |
| 124 | + if rc != 0 or stderr != "": |
| 125 | + |
| 126 | +From d2a9a539d72e01750dcc245a11962fe574777cc0 Mon Sep 17 00:00:00 2001 |
| 127 | +From: Tim Serong <tserong@suse.com> |
| 128 | +Date: Wed, 2 Nov 2022 14:27:47 +1100 |
| 129 | +Subject: [PATCH 4/6] ceph-crash: drop privleges to run as "ceph" user, rather |
| 130 | + than root |
| 131 | + |
| 132 | +If privileges cannot be dropped, log an error and exit. This commit |
| 133 | +also catches and logs exceptions when scraping the crash path, without |
| 134 | +which ceph-crash would just exit if it encountered an error. |
| 135 | + |
| 136 | +Fixes: CVE-2022-3650 |
| 137 | +Fixes: https://tracker.ceph.com/issues/57967 |
| 138 | +Signed-off-by: Tim Serong <tserong@suse.com> |
| 139 | +(cherry picked from commit 130c9626598bc3a75942161e6cce7c664c447382) |
| 140 | +--- |
| 141 | + src/ceph-crash.in | 24 +++++++++++++++++++++++- |
| 142 | + 1 file changed, 23 insertions(+), 1 deletion(-) |
| 143 | + |
| 144 | +diff --git a/src/ceph-crash.in b/src/ceph-crash.in |
| 145 | +index 453efb7aa10d0..d5c7260614e49 100755 |
| 146 | +--- a/src/ceph-crash.in |
| 147 | ++++ b/src/ceph-crash.in |
| 148 | +@@ -3,8 +3,10 @@ |
| 149 | + # vim: ts=4 sw=4 smarttab expandtab |
| 150 | + |
| 151 | + import argparse |
| 152 | ++import grp |
| 153 | + import logging |
| 154 | + import os |
| 155 | ++import pwd |
| 156 | + import signal |
| 157 | + import socket |
| 158 | + import subprocess |
| 159 | +@@ -88,8 +90,25 @@ def handler(signum, frame): |
| 160 | + sys.exit(0) |
| 161 | + |
| 162 | + |
| 163 | ++def drop_privs(): |
| 164 | ++ if os.getuid() == 0: |
| 165 | ++ try: |
| 166 | ++ ceph_uid = pwd.getpwnam("ceph").pw_uid |
| 167 | ++ ceph_gid = grp.getgrnam("ceph").gr_gid |
| 168 | ++ os.setgroups([]) |
| 169 | ++ os.setgid(ceph_gid) |
| 170 | ++ os.setuid(ceph_uid) |
| 171 | ++ except Exception as e: |
| 172 | ++ log.error(f"Unable to drop privileges: {e}") |
| 173 | ++ sys.exit(1) |
| 174 | ++ |
| 175 | ++ |
| 176 | + def main(): |
| 177 | + global auth_names |
| 178 | ++ |
| 179 | ++ # run as unprivileged ceph user |
| 180 | ++ drop_privs() |
| 181 | ++ |
| 182 | + # exit code 0 on SIGINT, SIGTERM |
| 183 | + signal.signal(signal.SIGINT, handler) |
| 184 | + signal.signal(signal.SIGTERM, handler) |
| 185 | +@@ -108,7 +127,10 @@ def main(): |
| 186 | + |
| 187 | + log.info("monitoring path %s, delay %ds" % (args.path, args.delay * 60.0)) |
| 188 | + while True: |
| 189 | +- scrape_path(args.path) |
| 190 | ++ try: |
| 191 | ++ scrape_path(args.path) |
| 192 | ++ except Exception as e: |
| 193 | ++ log.error(f"Error scraping {args.path}: {e}") |
| 194 | + if args.delay == 0: |
| 195 | + sys.exit(0) |
| 196 | + time.sleep(args.delay * 60) |
| 197 | + |
| 198 | +From 1a990887fc604674bb64e2b85b971522c72d7cd0 Mon Sep 17 00:00:00 2001 |
| 199 | +From: Tim Serong <tserong@suse.com> |
| 200 | +Date: Thu, 8 Dec 2022 11:09:16 +1100 |
| 201 | +Subject: [PATCH 5/6] qa/workunits/rados/test_crash: chown crash files to ceph |
| 202 | + user |
| 203 | + |
| 204 | +Fixes: https://tracker.ceph.com/issues/58098 |
| 205 | +Signed-off-by: Tim Serong <tserong@suse.com> |
| 206 | +(cherry picked from commit 93c0456159a87bb9c28b9b60998baeba1600af5f) |
| 207 | +--- |
| 208 | + qa/workunits/rados/test_crash.sh | 5 +++++ |
| 209 | + 1 file changed, 5 insertions(+) |
| 210 | + |
| 211 | +diff --git a/qa/workunits/rados/test_crash.sh b/qa/workunits/rados/test_crash.sh |
| 212 | +index 6608d7872e232..26a4c9bdc151f 100755 |
| 213 | +--- a/qa/workunits/rados/test_crash.sh |
| 214 | ++++ b/qa/workunits/rados/test_crash.sh |
| 215 | +@@ -24,6 +24,11 @@ for f in $(find $TESTDIR/archive/coredump -type f); do |
| 216 | + fi |
| 217 | + done |
| 218 | + |
| 219 | ++# ceph-crash runs as the unprivileged "ceph" user, but when under test |
| 220 | ++# the ceph osd daemons are running as root, so their crash files aren't |
| 221 | ++# readable. let's chown them so they behave as they would in real life. |
| 222 | ++sudo chown -R ceph:ceph /var/lib/ceph/crash |
| 223 | ++ |
| 224 | + # let daemon find crashdumps on startup |
| 225 | + sudo systemctl restart ceph-crash |
| 226 | + sleep 30 |
| 227 | + |
| 228 | +From 541ad16f64c93fc966ee167b9ef1ace1f5156678 Mon Sep 17 00:00:00 2001 |
| 229 | +From: Tim Serong <tserong@suse.com> |
| 230 | +Date: Thu, 8 Dec 2022 11:54:17 +1100 |
| 231 | +Subject: [PATCH 6/6] ceph-crash: log warning if crash directory unreadable |
| 232 | + |
| 233 | +This is to aid in debugging in case crashes aren't posted as expected |
| 234 | +(see https://tracker.ceph.com/issues/58098 for discussion). |
| 235 | + |
| 236 | +Signed-off-by: Tim Serong <tserong@suse.com> |
| 237 | +(cherry picked from commit d139f6d112e6118f0f458dbfff9550b3ce312d20) |
| 238 | +--- |
| 239 | + src/ceph-crash.in | 3 +++ |
| 240 | + 1 file changed, 3 insertions(+) |
| 241 | + |
| 242 | +diff --git a/src/ceph-crash.in b/src/ceph-crash.in |
| 243 | +index d5c7260614e49..74e50e2b253f3 100755 |
| 244 | +--- a/src/ceph-crash.in |
| 245 | ++++ b/src/ceph-crash.in |
| 246 | +@@ -66,6 +66,9 @@ def post_crash(path): |
| 247 | + def scrape_path(path): |
| 248 | + for p in os.listdir(path): |
| 249 | + crashpath = os.path.join(path, p) |
| 250 | ++ if not os.access(crashpath, os.R_OK): |
| 251 | ++ log.warning('unable to read crash path %s' % (crashpath)) |
| 252 | ++ continue |
| 253 | + metapath = os.path.join(crashpath, 'meta') |
| 254 | + donepath = os.path.join(crashpath, 'done') |
| 255 | + if os.path.isfile(metapath): |
0 commit comments