Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

printsiginfo.c 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
  3. * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
  4. * Copyright (c) 1993-1996 Rick Sladkey <jrs@world.std.com>
  5. * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
  6. * Copyright (c) 2001 John Hughes <john@Calva.COM>
  7. * Copyright (c) 2013 Denys Vlasenko <vda.linux@googlemail.com>
  8. * Copyright (c) 2011-2015 Dmitry V. Levin <ldv@altlinux.org>
  9. * Copyright (c) 2015 Elvira Khabirova <lineprinter0@gmail.com>
  10. * Copyright (c) 2015-2018 The strace developers.
  11. * All rights reserved.
  12. *
  13. * SPDX-License-Identifier: LGPL-2.1-or-later
  14. */
  15. #include "defs.h"
  16. #include DEF_MPERS_TYPE(siginfo_t)
  17. #include <signal.h>
  18. #include <linux/audit.h>
  19. #include MPERS_DEFS
  20. #include "nr_prefix.c"
  21. #include "print_fields.h"
  22. #ifndef IN_MPERS
  23. # include "printsiginfo.h"
  24. #endif
  25. #define XLAT_MACROS_ONLY
  26. /* For xlat/audit_arch.h */
  27. # include "xlat/elf_em.h"
  28. #undef XLAT_MACROS_ONLY
  29. #include "xlat/audit_arch.h"
  30. #include "xlat/sigbus_codes.h"
  31. #include "xlat/sigchld_codes.h"
  32. #include "xlat/sigfpe_codes.h"
  33. #include "xlat/sigill_codes.h"
  34. #include "xlat/siginfo_codes.h"
  35. #include "xlat/sigpoll_codes.h"
  36. #include "xlat/sigprof_codes.h"
  37. #include "xlat/sigsegv_codes.h"
  38. #include "xlat/sigsys_codes.h"
  39. #include "xlat/sigtrap_codes.h"
  40. #ifdef SIGEMT
  41. # include "xlat/sigemt_codes.h"
  42. #endif
  43. #ifndef SI_FROMUSER
  44. # define SI_FROMUSER(sip) ((sip)->si_code <= 0)
  45. #endif
  46. static void
  47. printsigsource(const siginfo_t *sip)
  48. {
  49. tprintf(", si_pid=%u, si_uid=%u",
  50. (unsigned int) sip->si_pid,
  51. (unsigned int) sip->si_uid);
  52. }
  53. static void
  54. printsigval(const siginfo_t *sip)
  55. {
  56. tprintf(", si_value={int=%d, ptr=", sip->si_int);
  57. printaddr(ptr_to_kulong(sip->si_ptr));
  58. tprints("}");
  59. }
  60. static void
  61. print_si_code(int si_signo, unsigned int si_code)
  62. {
  63. const char *code = xlookup(siginfo_codes, si_code);
  64. if (!code) {
  65. switch (si_signo) {
  66. case SIGTRAP:
  67. code = xlookup(sigtrap_codes, si_code);
  68. break;
  69. case SIGCHLD:
  70. code = xlookup(sigchld_codes, si_code);
  71. break;
  72. case SIGPOLL:
  73. code = xlookup(sigpoll_codes, si_code);
  74. break;
  75. case SIGPROF:
  76. code = xlookup(sigprof_codes, si_code);
  77. break;
  78. case SIGILL:
  79. code = xlookup(sigill_codes, si_code);
  80. break;
  81. #ifdef SIGEMT
  82. case SIGEMT:
  83. code = xlookup(sigemt_codes, si_code);
  84. break;
  85. #endif
  86. case SIGFPE:
  87. code = xlookup(sigfpe_codes, si_code);
  88. break;
  89. case SIGSEGV:
  90. code = xlookup(sigsegv_codes, si_code);
  91. break;
  92. case SIGBUS:
  93. code = xlookup(sigbus_codes, si_code);
  94. break;
  95. case SIGSYS:
  96. code = xlookup(sigsys_codes, si_code);
  97. break;
  98. }
  99. }
  100. print_xlat_ex(si_code, code, XLAT_STYLE_DEFAULT);
  101. }
  102. static void
  103. print_si_info(const siginfo_t *sip)
  104. {
  105. if (sip->si_errno)
  106. PRINT_FIELD_ERR_U(", ", *sip, si_errno);
  107. if (SI_FROMUSER(sip)) {
  108. switch (sip->si_code) {
  109. case SI_USER:
  110. printsigsource(sip);
  111. break;
  112. case SI_TKILL:
  113. printsigsource(sip);
  114. break;
  115. #if defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN
  116. case SI_TIMER:
  117. tprintf(", si_timerid=%#x, si_overrun=%d",
  118. sip->si_timerid, sip->si_overrun);
  119. printsigval(sip);
  120. break;
  121. #endif
  122. default:
  123. printsigsource(sip);
  124. if (sip->si_ptr)
  125. printsigval(sip);
  126. break;
  127. }
  128. } else {
  129. switch (sip->si_signo) {
  130. case SIGCHLD:
  131. printsigsource(sip);
  132. tprints(", si_status=");
  133. if (sip->si_code == CLD_EXITED)
  134. tprintf("%d", sip->si_status);
  135. else
  136. printsignal(sip->si_status);
  137. tprintf(", si_utime=%llu, si_stime=%llu",
  138. zero_extend_signed_to_ull(sip->si_utime),
  139. zero_extend_signed_to_ull(sip->si_stime));
  140. break;
  141. case SIGILL: case SIGFPE:
  142. case SIGSEGV: case SIGBUS:
  143. tprints(", si_addr=");
  144. printaddr(ptr_to_kulong(sip->si_addr));
  145. break;
  146. case SIGPOLL:
  147. switch (sip->si_code) {
  148. case POLL_IN: case POLL_OUT: case POLL_MSG:
  149. tprintf(", si_band=%ld",
  150. (long) sip->si_band);
  151. break;
  152. }
  153. break;
  154. #ifdef HAVE_SIGINFO_T_SI_SYSCALL
  155. case SIGSYS: {
  156. /*
  157. * Note that we can safely use the personlity set in
  158. * current_personality here (and don't have to guess it
  159. * based on X32_SYSCALL_BIT and si_arch, for example):
  160. * - The signal is delivered as a result of seccomp
  161. * filtering to the process executing forbidden
  162. * syscall.
  163. * - We have set the personality for the tracee during
  164. * the syscall entering.
  165. * - The current_personality is reliably switched in
  166. * the next_event routine, it is set to the
  167. * personality of the last call made (the one that
  168. * triggered the signal delivery).
  169. * - Looks like there are no other cases where SIGSYS
  170. * is delivered from the kernel so far.
  171. */
  172. const char *scname = syscall_name(shuffle_scno(
  173. (unsigned) sip->si_syscall));
  174. tprints(", si_call_addr=");
  175. printaddr(ptr_to_kulong(sip->si_call_addr));
  176. tprints(", si_syscall=");
  177. if (scname)
  178. tprintf("%s%s",
  179. nr_prefix(sip->si_syscall), scname);
  180. else
  181. tprintf("%u", (unsigned) sip->si_syscall);
  182. tprints(", si_arch=");
  183. printxval(audit_arch, sip->si_arch, "AUDIT_ARCH_???");
  184. break;
  185. }
  186. #endif
  187. default:
  188. if (sip->si_pid || sip->si_uid)
  189. printsigsource(sip);
  190. if (sip->si_ptr)
  191. printsigval(sip);
  192. }
  193. }
  194. }
  195. #ifdef IN_MPERS
  196. static
  197. #endif
  198. void
  199. printsiginfo(const siginfo_t *sip)
  200. {
  201. if (sip->si_signo == 0) {
  202. tprints("{}");
  203. return;
  204. }
  205. tprints("{si_signo=");
  206. printsignal(sip->si_signo);
  207. tprints(", si_code=");
  208. print_si_code(sip->si_signo, sip->si_code);
  209. #ifdef SI_NOINFO
  210. if (sip->si_code != SI_NOINFO)
  211. #endif
  212. print_si_info(sip);
  213. tprints("}");
  214. }
  215. MPERS_PRINTER_DECL(void, printsiginfo_at,
  216. struct tcb *const tcp, const kernel_ulong_t addr)
  217. {
  218. siginfo_t si;
  219. if (!umove_or_printaddr(tcp, addr, &si))
  220. printsiginfo(&si);
  221. }
  222. static bool
  223. print_siginfo_t(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
  224. {
  225. printsiginfo((const siginfo_t *) elem_buf);
  226. return true;
  227. }
  228. MPERS_PRINTER_DECL(void, print_siginfo_array, struct tcb *const tcp,
  229. const kernel_ulong_t addr, const kernel_ulong_t len)
  230. {
  231. siginfo_t si;
  232. print_array(tcp, addr, len, &si, sizeof(si),
  233. tfetch_mem, print_siginfo_t, 0);
  234. }