]> granicus.if.org Git - strace/blob - printsiginfo.c
maint: update for linux v5.3-rc8
[strace] / printsiginfo.c
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
16 #include "defs.h"
17
18 #include DEF_MPERS_TYPE(siginfo_t)
19
20 #include <signal.h>
21 #include <linux/audit.h>
22
23 #include MPERS_DEFS
24
25 #include "nr_prefix.c"
26
27 #include "print_fields.h"
28
29 #ifndef IN_MPERS
30 # include "printsiginfo.h"
31 #endif
32
33 #define XLAT_MACROS_ONLY
34 /* For xlat/audit_arch.h */
35 # include "xlat/elf_em.h"
36 #undef XLAT_MACROS_ONLY
37
38 #include "xlat/audit_arch.h"
39 #include "xlat/sigbus_codes.h"
40 #include "xlat/sigchld_codes.h"
41 #include "xlat/sigfpe_codes.h"
42 #include "xlat/sigill_codes.h"
43 #include "xlat/siginfo_codes.h"
44 #include "xlat/sigpoll_codes.h"
45 #include "xlat/sigprof_codes.h"
46 #include "xlat/sigsegv_codes.h"
47 #include "xlat/sigsys_codes.h"
48 #include "xlat/sigtrap_codes.h"
49
50 #ifdef SIGEMT
51 # include "xlat/sigemt_codes.h"
52 #endif
53
54 #ifndef SI_FROMUSER
55 # define SI_FROMUSER(sip)       ((sip)->si_code <= 0)
56 #endif
57
58 static void
59 printsigsource(const siginfo_t *sip)
60 {
61         tprintf(", si_pid=%u, si_uid=%u",
62                 (unsigned int) sip->si_pid,
63                 (unsigned int) sip->si_uid);
64 }
65
66 static void
67 printsigval(const siginfo_t *sip)
68 {
69         tprintf(", si_value={int=%d, ptr=", sip->si_int);
70         printaddr(ptr_to_kulong(sip->si_ptr));
71         tprints("}");
72 }
73
74 static void
75 print_si_code(int si_signo, unsigned int si_code)
76 {
77         const char *code = xlookup(siginfo_codes, si_code);
78
79         if (!code) {
80                 switch (si_signo) {
81                 case SIGTRAP:
82                         code = xlookup(sigtrap_codes, si_code);
83                         break;
84                 case SIGCHLD:
85                         code = xlookup(sigchld_codes, si_code);
86                         break;
87                 case SIGPOLL:
88                         code = xlookup(sigpoll_codes, si_code);
89                         break;
90                 case SIGPROF:
91                         code = xlookup(sigprof_codes, si_code);
92                         break;
93                 case SIGILL:
94                         code = xlookup(sigill_codes, si_code);
95                         break;
96 #ifdef SIGEMT
97                 case SIGEMT:
98                         code = xlookup(sigemt_codes, si_code);
99                         break;
100 #endif
101                 case SIGFPE:
102                         code = xlookup(sigfpe_codes, si_code);
103                         break;
104                 case SIGSEGV:
105                         code = xlookup(sigsegv_codes, si_code);
106                         break;
107                 case SIGBUS:
108                         code = xlookup(sigbus_codes, si_code);
109                         break;
110                 case SIGSYS:
111                         code = xlookup(sigsys_codes, si_code);
112                         break;
113                 }
114         }
115
116         print_xlat_ex(si_code, code, XLAT_STYLE_DEFAULT);
117 }
118
119 static void
120 print_si_info(const siginfo_t *sip)
121 {
122         if (sip->si_errno)
123                 PRINT_FIELD_ERR_U(", ", *sip, si_errno);
124
125         if (SI_FROMUSER(sip)) {
126                 switch (sip->si_code) {
127                 case SI_USER:
128                         printsigsource(sip);
129                         break;
130                 case SI_TKILL:
131                         printsigsource(sip);
132                         break;
133 #if defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN
134                 case SI_TIMER:
135                         tprintf(", si_timerid=%#x, si_overrun=%d",
136                                 sip->si_timerid, sip->si_overrun);
137                         printsigval(sip);
138                         break;
139 #endif
140                 default:
141                         printsigsource(sip);
142                         if (sip->si_ptr)
143                                 printsigval(sip);
144                         break;
145                 }
146         } else {
147                 switch (sip->si_signo) {
148                 case SIGCHLD:
149                         printsigsource(sip);
150                         tprints(", si_status=");
151                         if (sip->si_code == CLD_EXITED)
152                                 tprintf("%d", sip->si_status);
153                         else
154                                 printsignal(sip->si_status);
155                         tprintf(", si_utime=%llu, si_stime=%llu",
156                                 zero_extend_signed_to_ull(sip->si_utime),
157                                 zero_extend_signed_to_ull(sip->si_stime));
158                         break;
159                 case SIGILL: case SIGFPE:
160                 case SIGSEGV: case SIGBUS:
161                         tprints(", si_addr=");
162                         printaddr(ptr_to_kulong(sip->si_addr));
163                         break;
164                 case SIGPOLL:
165                         switch (sip->si_code) {
166                         case POLL_IN: case POLL_OUT: case POLL_MSG:
167                                 tprintf(", si_band=%ld",
168                                         (long) sip->si_band);
169                                 break;
170                         }
171                         break;
172 #ifdef HAVE_SIGINFO_T_SI_SYSCALL
173                 case SIGSYS: {
174                         /*
175                          * Note that we can safely use the personlity set in
176                          * current_personality  here (and don't have to guess it
177                          * based on X32_SYSCALL_BIT and si_arch, for example):
178                          *  - The signal is delivered as a result of seccomp
179                          *    filtering to the process executing forbidden
180                          *    syscall.
181                          *  - We have set the personality for the tracee during
182                          *    the syscall entering.
183                          *  - The current_personality is reliably switched in
184                          *    the next_event routine, it is set to the
185                          *    personality of the last call made (the one that
186                          *    triggered the signal delivery).
187                          *  - Looks like there are no other cases where SIGSYS
188                          *    is delivered from the kernel so far.
189                          */
190                         const char *scname = syscall_name(shuffle_scno(
191                                 (unsigned) sip->si_syscall));
192
193                         tprints(", si_call_addr=");
194                         printaddr(ptr_to_kulong(sip->si_call_addr));
195                         tprints(", si_syscall=");
196                         if (scname)
197                                 tprintf("%s%s",
198                                         nr_prefix(sip->si_syscall), scname);
199                         else
200                                 tprintf("%u", (unsigned) sip->si_syscall);
201                         tprints(", si_arch=");
202                         printxval(audit_arch, sip->si_arch, "AUDIT_ARCH_???");
203                         break;
204                 }
205 #endif
206                 default:
207                         if (sip->si_pid || sip->si_uid)
208                                 printsigsource(sip);
209                         if (sip->si_ptr)
210                                 printsigval(sip);
211                 }
212         }
213 }
214
215 #ifdef IN_MPERS
216 static
217 #endif
218 void
219 printsiginfo(const siginfo_t *sip)
220 {
221         if (sip->si_signo == 0) {
222                 tprints("{}");
223                 return;
224         }
225         tprints("{si_signo=");
226         printsignal(sip->si_signo);
227
228         tprints(", si_code=");
229         print_si_code(sip->si_signo, sip->si_code);
230
231 #ifdef SI_NOINFO
232         if (sip->si_code != SI_NOINFO)
233 #endif
234                 print_si_info(sip);
235
236         tprints("}");
237 }
238
239 MPERS_PRINTER_DECL(void, printsiginfo_at,
240                    struct tcb *const tcp, const kernel_ulong_t addr)
241 {
242         siginfo_t si;
243
244         if (!umove_or_printaddr(tcp, addr, &si))
245                 printsiginfo(&si);
246 }
247
248 static bool
249 print_siginfo_t(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
250 {
251         printsiginfo((const siginfo_t *) elem_buf);
252         return true;
253 }
254
255 MPERS_PRINTER_DECL(void, print_siginfo_array, struct tcb *const tcp,
256                    const kernel_ulong_t addr, const kernel_ulong_t len)
257 {
258         siginfo_t si;
259
260         print_array(tcp, addr, len, &si, sizeof(si),
261                     tfetch_mem, print_siginfo_t, 0);
262 }