summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliott Hughes2018-04-25 19:00:14 -0500
committerElliott Hughes2018-04-26 10:19:17 -0500
commit70d8f289454c9b691ec5421b0ed0354b6baaace8 (patch)
tree065570ea913e9c631e13807522fa0361e5c26e5e
parentf88905d231367eeeb72379d9eb2debbadb47b788 (diff)
downloadplatform-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.cpp20
-rw-r--r--debuggerd/libdebuggerd/include/libdebuggerd/utility.h8
-rw-r--r--debuggerd/libdebuggerd/tombstone.cpp22
-rw-r--r--debuggerd/libdebuggerd/utility.cpp40
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
75void drop_capabilities(); 75void drop_capabilities();
76 76
77bool signal_has_si_addr(int si_signo, int si_code); 77bool signal_has_sender(const siginfo_t*, pid_t caller_pid);
78const char* get_signame(int sig); 78bool signal_has_si_addr(const siginfo_t*);
79const char* get_sigcode(int signo, int code); 79void get_signal_sender(char* buf, size_t n, const siginfo_t*);
80const char* get_signame(const siginfo_t*);
81const 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
105static void dump_signal_info(log_t* log, const siginfo_t* si) { 105static 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
119static void dump_thread_info(log_t* log, const ThreadInfo& thread_info) { 125static 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
257bool signal_has_si_addr(int si_signo, int si_code) { 257bool 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
275const char* get_signame(int sig) { 275bool 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
279void 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
283const 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
293const char* get_sigcode(int signo, int code) { 301const 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";