diff options
author | Elliott Hughes | 2018-04-25 19:00:14 -0500 |
---|---|---|
committer | Elliott Hughes | 2018-04-26 10:19:17 -0500 |
commit | 70d8f289454c9b691ec5421b0ed0354b6baaace8 (patch) | |
tree | 065570ea913e9c631e13807522fa0361e5c26e5e | |
parent | f88905d231367eeeb72379d9eb2debbadb47b788 (diff) | |
download | platform-system-core-70d8f289454c9b691ec5421b0ed0354b6baaace8.tar.gz platform-system-core-70d8f289454c9b691ec5421b0ed0354b6baaace8.tar.xz platform-system-core-70d8f289454c9b691ec5421b0ed0354b6baaace8.zip |
Show signal sender for SI_FROMUSER signals.
Suicide doesn't change:
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
But homicide now looks like this (this is `sleep 666` killed by
`kill -SEGV` as root:
signal 11 (SIGSEGV), code 0 (SI_USER from pid 4446, uid 0), fault addr --------
Bug: http://b/78594105
Test: manual
Change-Id: I8c2feafba8cc5a3db85e8250004d428a464c5d9e
-rw-r--r-- | debuggerd/handler/debuggerd_handler.cpp | 20 | ||||
-rw-r--r-- | debuggerd/libdebuggerd/include/libdebuggerd/utility.h | 8 | ||||
-rw-r--r-- | debuggerd/libdebuggerd/tombstone.cpp | 22 | ||||
-rw-r--r-- | debuggerd/libdebuggerd/utility.cpp | 40 |
4 files changed, 54 insertions, 36 deletions
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp index 05e6efa60..c07a34a70 100644 --- a/debuggerd/handler/debuggerd_handler.cpp +++ b/debuggerd/handler/debuggerd_handler.cpp | |||
@@ -169,24 +169,26 @@ static void log_signal_summary(const siginfo_t* info) { | |||
169 | return; | 169 | return; |
170 | } | 170 | } |
171 | 171 | ||
172 | const char* signal_name = get_signame(info->si_signo); | 172 | // Many signals don't have an address or sender. |
173 | bool has_address = signal_has_si_addr(info->si_signo, info->si_code); | ||
174 | |||
175 | // Many signals don't have an address. | ||
176 | char addr_desc[32] = ""; // ", fault addr 0x1234" | 173 | char addr_desc[32] = ""; // ", fault addr 0x1234" |
177 | if (has_address) { | 174 | if (signal_has_si_addr(info)) { |
178 | async_safe_format_buffer(addr_desc, sizeof(addr_desc), ", fault addr %p", info->si_addr); | 175 | async_safe_format_buffer(addr_desc, sizeof(addr_desc), ", fault addr %p", info->si_addr); |
179 | } | 176 | } |
177 | pid_t self_pid = __getpid(); | ||
178 | char sender_desc[32] = {}; // " from pid 1234, uid 666" | ||
179 | if (signal_has_sender(info, self_pid)) { | ||
180 | get_signal_sender(sender_desc, sizeof(sender_desc), info); | ||
181 | } | ||
180 | 182 | ||
181 | char main_thread_name[MAX_TASK_NAME_LEN + 1]; | 183 | char main_thread_name[MAX_TASK_NAME_LEN + 1]; |
182 | if (!get_main_thread_name(main_thread_name, sizeof(main_thread_name))) { | 184 | if (!get_main_thread_name(main_thread_name, sizeof(main_thread_name))) { |
183 | strncpy(main_thread_name, "<unknown>", sizeof(main_thread_name)); | 185 | strncpy(main_thread_name, "<unknown>", sizeof(main_thread_name)); |
184 | } | 186 | } |
185 | 187 | ||
186 | async_safe_format_log( | 188 | async_safe_format_log(ANDROID_LOG_FATAL, "libc", |
187 | ANDROID_LOG_FATAL, "libc", "Fatal signal %d (%s), code %d (%s)%s in tid %d (%s), pid %d (%s)", | 189 | "Fatal signal %d (%s), code %d (%s%s)%s in tid %d (%s), pid %d (%s)", |
188 | info->si_signo, signal_name, info->si_code, get_sigcode(info->si_signo, info->si_code), | 190 | info->si_signo, get_signame(info), info->si_code, get_sigcode(info), |
189 | addr_desc, __gettid(), thread_name, __getpid(), main_thread_name); | 191 | sender_desc, addr_desc, __gettid(), thread_name, self_pid, main_thread_name); |
190 | } | 192 | } |
191 | 193 | ||
192 | /* | 194 | /* |
diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h index 7b04e7192..7c5304e84 100644 --- a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h +++ b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h | |||
@@ -74,8 +74,10 @@ void read_with_default(const char* path, char* buf, size_t len, const char* defa | |||
74 | 74 | ||
75 | void drop_capabilities(); | 75 | void drop_capabilities(); |
76 | 76 | ||
77 | bool signal_has_si_addr(int si_signo, int si_code); | 77 | bool signal_has_sender(const siginfo_t*, pid_t caller_pid); |
78 | const char* get_signame(int sig); | 78 | bool signal_has_si_addr(const siginfo_t*); |
79 | const char* get_sigcode(int signo, int code); | 79 | void get_signal_sender(char* buf, size_t n, const siginfo_t*); |
80 | const char* get_signame(const siginfo_t*); | ||
81 | const char* get_sigcode(const siginfo_t*); | ||
80 | 82 | ||
81 | #endif // _DEBUGGERD_UTILITY_H | 83 | #endif // _DEBUGGERD_UTILITY_H |
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp index af8072e76..e11be1ea7 100644 --- a/debuggerd/libdebuggerd/tombstone.cpp +++ b/debuggerd/libdebuggerd/tombstone.cpp | |||
@@ -102,18 +102,24 @@ static void dump_probable_cause(log_t* log, const siginfo_t* si) { | |||
102 | if (!cause.empty()) _LOG(log, logtype::HEADER, "Cause: %s\n", cause.c_str()); | 102 | if (!cause.empty()) _LOG(log, logtype::HEADER, "Cause: %s\n", cause.c_str()); |
103 | } | 103 | } |
104 | 104 | ||
105 | static void dump_signal_info(log_t* log, const siginfo_t* si) { | 105 | static void dump_signal_info(log_t* log, const ThreadInfo& thread_info) { |
106 | char addr_desc[32]; // ", fault addr 0x1234" | 106 | char addr_desc[32]; // ", fault addr 0x1234" |
107 | if (signal_has_si_addr(si->si_signo, si->si_code)) { | 107 | if (signal_has_si_addr(thread_info.siginfo)) { |
108 | snprintf(addr_desc, sizeof(addr_desc), "%p", si->si_addr); | 108 | snprintf(addr_desc, sizeof(addr_desc), "%p", thread_info.siginfo->si_addr); |
109 | } else { | 109 | } else { |
110 | snprintf(addr_desc, sizeof(addr_desc), "--------"); | 110 | snprintf(addr_desc, sizeof(addr_desc), "--------"); |
111 | } | 111 | } |
112 | 112 | ||
113 | _LOG(log, logtype::HEADER, "signal %d (%s), code %d (%s), fault addr %s\n", si->si_signo, | 113 | char sender_desc[32] = {}; // " from pid 1234, uid 666" |
114 | get_signame(si->si_signo), si->si_code, get_sigcode(si->si_signo, si->si_code), addr_desc); | 114 | if (signal_has_sender(thread_info.siginfo, thread_info.pid)) { |
115 | get_signal_sender(sender_desc, sizeof(sender_desc), thread_info.siginfo); | ||
116 | } | ||
117 | |||
118 | _LOG(log, logtype::HEADER, "signal %d (%s), code %d (%s%s), fault addr %s\n", | ||
119 | thread_info.siginfo->si_signo, get_signame(thread_info.siginfo), | ||
120 | thread_info.siginfo->si_code, get_sigcode(thread_info.siginfo), sender_desc, addr_desc); | ||
115 | 121 | ||
116 | dump_probable_cause(log, si); | 122 | dump_probable_cause(log, thread_info.siginfo); |
117 | } | 123 | } |
118 | 124 | ||
119 | static void dump_thread_info(log_t* log, const ThreadInfo& thread_info) { | 125 | static void dump_thread_info(log_t* log, const ThreadInfo& thread_info) { |
@@ -412,7 +418,7 @@ static bool dump_thread(log_t* log, BacktraceMap* map, Memory* process_memory, | |||
412 | dump_thread_info(log, thread_info); | 418 | dump_thread_info(log, thread_info); |
413 | 419 | ||
414 | if (thread_info.siginfo) { | 420 | if (thread_info.siginfo) { |
415 | dump_signal_info(log, thread_info.siginfo); | 421 | dump_signal_info(log, thread_info); |
416 | } | 422 | } |
417 | 423 | ||
418 | if (primary_thread) { | 424 | if (primary_thread) { |
@@ -442,7 +448,7 @@ static bool dump_thread(log_t* log, BacktraceMap* map, Memory* process_memory, | |||
442 | if (map) { | 448 | if (map) { |
443 | uint64_t addr = 0; | 449 | uint64_t addr = 0; |
444 | siginfo_t* si = thread_info.siginfo; | 450 | siginfo_t* si = thread_info.siginfo; |
445 | if (signal_has_si_addr(si->si_signo, si->si_code)) { | 451 | if (signal_has_si_addr(si)) { |
446 | addr = reinterpret_cast<uint64_t>(si->si_addr); | 452 | addr = reinterpret_cast<uint64_t>(si->si_addr); |
447 | } | 453 | } |
448 | dump_all_maps(log, map, process_memory, addr); | 454 | dump_all_maps(log, map, process_memory, addr); |
diff --git a/debuggerd/libdebuggerd/utility.cpp b/debuggerd/libdebuggerd/utility.cpp index 1ad180073..1f6f3c803 100644 --- a/debuggerd/libdebuggerd/utility.cpp +++ b/debuggerd/libdebuggerd/utility.cpp | |||
@@ -254,13 +254,13 @@ void drop_capabilities() { | |||
254 | } | 254 | } |
255 | } | 255 | } |
256 | 256 | ||
257 | bool signal_has_si_addr(int si_signo, int si_code) { | 257 | bool signal_has_si_addr(const siginfo_t* si) { |
258 | // Manually sent signals won't have si_addr. | 258 | // Manually sent signals won't have si_addr. |
259 | if (si_code == SI_USER || si_code == SI_QUEUE || si_code == SI_TKILL) { | 259 | if (si->si_code == SI_USER || si->si_code == SI_QUEUE || si->si_code == SI_TKILL) { |
260 | return false; | 260 | return false; |
261 | } | 261 | } |
262 | 262 | ||
263 | switch (si_signo) { | 263 | switch (si->si_signo) { |
264 | case SIGBUS: | 264 | case SIGBUS: |
265 | case SIGFPE: | 265 | case SIGFPE: |
266 | case SIGILL: | 266 | case SIGILL: |
@@ -272,8 +272,16 @@ bool signal_has_si_addr(int si_signo, int si_code) { | |||
272 | } | 272 | } |
273 | } | 273 | } |
274 | 274 | ||
275 | const char* get_signame(int sig) { | 275 | bool signal_has_sender(const siginfo_t* si, pid_t caller_pid) { |
276 | switch (sig) { | 276 | return SI_FROMUSER(si) && (si->si_pid != 0) && (si->si_pid != caller_pid); |
277 | } | ||
278 | |||
279 | void get_signal_sender(char* buf, size_t n, const siginfo_t* si) { | ||
280 | snprintf(buf, n, " from pid %d, uid %d", si->si_pid, si->si_uid); | ||
281 | } | ||
282 | |||
283 | const char* get_signame(const siginfo_t* si) { | ||
284 | switch (si->si_signo) { | ||
277 | case SIGABRT: return "SIGABRT"; | 285 | case SIGABRT: return "SIGABRT"; |
278 | case SIGBUS: return "SIGBUS"; | 286 | case SIGBUS: return "SIGBUS"; |
279 | case SIGFPE: return "SIGFPE"; | 287 | case SIGFPE: return "SIGFPE"; |
@@ -290,11 +298,11 @@ const char* get_signame(int sig) { | |||
290 | } | 298 | } |
291 | } | 299 | } |
292 | 300 | ||
293 | const char* get_sigcode(int signo, int code) { | 301 | const char* get_sigcode(const siginfo_t* si) { |
294 | // Try the signal-specific codes... | 302 | // Try the signal-specific codes... |
295 | switch (signo) { | 303 | switch (si->si_signo) { |
296 | case SIGILL: | 304 | case SIGILL: |
297 | switch (code) { | 305 | switch (si->si_code) { |
298 | case ILL_ILLOPC: return "ILL_ILLOPC"; | 306 | case ILL_ILLOPC: return "ILL_ILLOPC"; |
299 | case ILL_ILLOPN: return "ILL_ILLOPN"; | 307 | case ILL_ILLOPN: return "ILL_ILLOPN"; |
300 | case ILL_ILLADR: return "ILL_ILLADR"; | 308 | case ILL_ILLADR: return "ILL_ILLADR"; |
@@ -307,7 +315,7 @@ const char* get_sigcode(int signo, int code) { | |||
307 | static_assert(NSIGILL == ILL_BADSTK, "missing ILL_* si_code"); | 315 | static_assert(NSIGILL == ILL_BADSTK, "missing ILL_* si_code"); |
308 | break; | 316 | break; |
309 | case SIGBUS: | 317 | case SIGBUS: |
310 | switch (code) { | 318 | switch (si->si_code) { |
311 | case BUS_ADRALN: return "BUS_ADRALN"; | 319 | case BUS_ADRALN: return "BUS_ADRALN"; |
312 | case BUS_ADRERR: return "BUS_ADRERR"; | 320 | case BUS_ADRERR: return "BUS_ADRERR"; |
313 | case BUS_OBJERR: return "BUS_OBJERR"; | 321 | case BUS_OBJERR: return "BUS_OBJERR"; |
@@ -317,7 +325,7 @@ const char* get_sigcode(int signo, int code) { | |||
317 | static_assert(NSIGBUS == BUS_MCEERR_AO, "missing BUS_* si_code"); | 325 | static_assert(NSIGBUS == BUS_MCEERR_AO, "missing BUS_* si_code"); |
318 | break; | 326 | break; |
319 | case SIGFPE: | 327 | case SIGFPE: |
320 | switch (code) { | 328 | switch (si->si_code) { |
321 | case FPE_INTDIV: return "FPE_INTDIV"; | 329 | case FPE_INTDIV: return "FPE_INTDIV"; |
322 | case FPE_INTOVF: return "FPE_INTOVF"; | 330 | case FPE_INTOVF: return "FPE_INTOVF"; |
323 | case FPE_FLTDIV: return "FPE_FLTDIV"; | 331 | case FPE_FLTDIV: return "FPE_FLTDIV"; |
@@ -330,7 +338,7 @@ const char* get_sigcode(int signo, int code) { | |||
330 | static_assert(NSIGFPE == FPE_FLTSUB, "missing FPE_* si_code"); | 338 | static_assert(NSIGFPE == FPE_FLTSUB, "missing FPE_* si_code"); |
331 | break; | 339 | break; |
332 | case SIGSEGV: | 340 | case SIGSEGV: |
333 | switch (code) { | 341 | switch (si->si_code) { |
334 | case SEGV_MAPERR: return "SEGV_MAPERR"; | 342 | case SEGV_MAPERR: return "SEGV_MAPERR"; |
335 | case SEGV_ACCERR: return "SEGV_ACCERR"; | 343 | case SEGV_ACCERR: return "SEGV_ACCERR"; |
336 | #if defined(SEGV_BNDERR) | 344 | #if defined(SEGV_BNDERR) |
@@ -350,21 +358,21 @@ const char* get_sigcode(int signo, int code) { | |||
350 | break; | 358 | break; |
351 | #if defined(SYS_SECCOMP) // Our glibc is too old, and we build this for the host too. | 359 | #if defined(SYS_SECCOMP) // Our glibc is too old, and we build this for the host too. |
352 | case SIGSYS: | 360 | case SIGSYS: |
353 | switch (code) { | 361 | switch (si->si_code) { |
354 | case SYS_SECCOMP: return "SYS_SECCOMP"; | 362 | case SYS_SECCOMP: return "SYS_SECCOMP"; |
355 | } | 363 | } |
356 | static_assert(NSIGSYS == SYS_SECCOMP, "missing SYS_* si_code"); | 364 | static_assert(NSIGSYS == SYS_SECCOMP, "missing SYS_* si_code"); |
357 | break; | 365 | break; |
358 | #endif | 366 | #endif |
359 | case SIGTRAP: | 367 | case SIGTRAP: |
360 | switch (code) { | 368 | switch (si->si_code) { |
361 | case TRAP_BRKPT: return "TRAP_BRKPT"; | 369 | case TRAP_BRKPT: return "TRAP_BRKPT"; |
362 | case TRAP_TRACE: return "TRAP_TRACE"; | 370 | case TRAP_TRACE: return "TRAP_TRACE"; |
363 | case TRAP_BRANCH: return "TRAP_BRANCH"; | 371 | case TRAP_BRANCH: return "TRAP_BRANCH"; |
364 | case TRAP_HWBKPT: return "TRAP_HWBKPT"; | 372 | case TRAP_HWBKPT: return "TRAP_HWBKPT"; |
365 | } | 373 | } |
366 | if ((code & 0xff) == SIGTRAP) { | 374 | if ((si->si_code & 0xff) == SIGTRAP) { |
367 | switch ((code >> 8) & 0xff) { | 375 | switch ((si->si_code >> 8) & 0xff) { |
368 | case PTRACE_EVENT_FORK: | 376 | case PTRACE_EVENT_FORK: |
369 | return "PTRACE_EVENT_FORK"; | 377 | return "PTRACE_EVENT_FORK"; |
370 | case PTRACE_EVENT_VFORK: | 378 | case PTRACE_EVENT_VFORK: |
@@ -387,7 +395,7 @@ const char* get_sigcode(int signo, int code) { | |||
387 | break; | 395 | break; |
388 | } | 396 | } |
389 | // Then the other codes... | 397 | // Then the other codes... |
390 | switch (code) { | 398 | switch (si->si_code) { |
391 | case SI_USER: return "SI_USER"; | 399 | case SI_USER: return "SI_USER"; |
392 | case SI_KERNEL: return "SI_KERNEL"; | 400 | case SI_KERNEL: return "SI_KERNEL"; |
393 | case SI_QUEUE: return "SI_QUEUE"; | 401 | case SI_QUEUE: return "SI_QUEUE"; |