]> granicus.if.org Git - strace/blob - printsiginfo.c
Do not sign-extend siginfo_t.si_syscall
[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  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 #include "defs.h"
36
37 #include DEF_MPERS_TYPE(siginfo_t)
38
39 #include <signal.h>
40 #include <linux/audit.h>
41
42 #include MPERS_DEFS
43
44 #ifndef IN_MPERS
45 #include "printsiginfo.h"
46 #endif
47
48 #include "xlat/audit_arch.h"
49 #include "xlat/sigbus_codes.h"
50 #include "xlat/sigchld_codes.h"
51 #include "xlat/sigfpe_codes.h"
52 #include "xlat/sigill_codes.h"
53 #include "xlat/siginfo_codes.h"
54 #include "xlat/sigpoll_codes.h"
55 #include "xlat/sigprof_codes.h"
56 #include "xlat/sigsegv_codes.h"
57 #include "xlat/sigsys_codes.h"
58 #include "xlat/sigtrap_codes.h"
59
60 #ifdef SIGEMT
61 # include "xlat/sigemt_codes.h"
62 #endif
63
64 #ifndef SI_FROMUSER
65 # define SI_FROMUSER(sip)       ((sip)->si_code <= 0)
66 #endif
67
68 static void
69 printsigsource(const siginfo_t *sip)
70 {
71         tprintf(", si_pid=%u, si_uid=%u",
72                 (unsigned int) sip->si_pid,
73                 (unsigned int) sip->si_uid);
74 }
75
76 static void
77 printsigval(const siginfo_t *sip, bool verbose)
78 {
79         if (!verbose)
80                 tprints(", ...");
81         else
82                 tprintf(", si_value={int=%d, ptr=%#lx}",
83                         sip->si_int,
84                         (unsigned long) sip->si_ptr);
85 }
86
87 static void
88 print_si_code(int si_signo, int si_code)
89 {
90         const char *code = xlookup(siginfo_codes, si_code);
91
92         if (!code) {
93                 switch (si_signo) {
94                 case SIGTRAP:
95                         code = xlookup(sigtrap_codes, si_code);
96                         break;
97                 case SIGCHLD:
98                         code = xlookup(sigchld_codes, si_code);
99                         break;
100                 case SIGPOLL:
101                         code = xlookup(sigpoll_codes, si_code);
102                         break;
103                 case SIGPROF:
104                         code = xlookup(sigprof_codes, si_code);
105                         break;
106                 case SIGILL:
107                         code = xlookup(sigill_codes, si_code);
108                         break;
109 #ifdef SIGEMT
110                 case SIGEMT:
111                         code = xlookup(sigemt_codes, si_code);
112                         break;
113 #endif
114                 case SIGFPE:
115                         code = xlookup(sigfpe_codes, si_code);
116                         break;
117                 case SIGSEGV:
118                         code = xlookup(sigsegv_codes, si_code);
119                         break;
120                 case SIGBUS:
121                         code = xlookup(sigbus_codes, si_code);
122                         break;
123                 case SIGSYS:
124                         code = xlookup(sigsys_codes, si_code);
125                         break;
126                 }
127         }
128
129         if (code)
130                 tprints(code);
131         else
132                 tprintf("%#x", si_code);
133 }
134
135 static void
136 print_si_info(const siginfo_t *sip, bool verbose)
137 {
138         if (sip->si_errno) {
139                 tprints(", si_errno=");
140                 if ((unsigned) sip->si_errno < nerrnos
141                     && errnoent[sip->si_errno])
142                         tprints(errnoent[sip->si_errno]);
143                 else
144                         tprintf("%d", sip->si_errno);
145         }
146
147         if (SI_FROMUSER(sip)) {
148                 switch (sip->si_code) {
149                 case SI_USER:
150                         printsigsource(sip);
151                         break;
152                 case SI_TKILL:
153                         printsigsource(sip);
154                         break;
155 #if defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN
156                 case SI_TIMER:
157                         tprintf(", si_timerid=%#x, si_overrun=%d",
158                                 sip->si_timerid, sip->si_overrun);
159                         printsigval(sip, verbose);
160                         break;
161 #endif
162                 default:
163                         printsigsource(sip);
164                         if (sip->si_ptr)
165                                 printsigval(sip, verbose);
166                         break;
167                 }
168         } else {
169                 switch (sip->si_signo) {
170                 case SIGCHLD:
171                         printsigsource(sip);
172                         tprints(", si_status=");
173                         if (sip->si_code == CLD_EXITED)
174                                 tprintf("%d", sip->si_status);
175                         else
176                                 printsignal(sip->si_status);
177                         if (!verbose)
178                                 tprints(", ...");
179                         else
180                                 tprintf(", si_utime=%llu, si_stime=%llu",
181                                         (unsigned long long) sip->si_utime,
182                                         (unsigned long long) sip->si_stime);
183                         break;
184                 case SIGILL: case SIGFPE:
185                 case SIGSEGV: case SIGBUS:
186                         tprintf(", si_addr=%#lx",
187                                 (unsigned long) sip->si_addr);
188                         break;
189                 case SIGPOLL:
190                         switch (sip->si_code) {
191                         case POLL_IN: case POLL_OUT: case POLL_MSG:
192                                 tprintf(", si_band=%ld",
193                                         (long) sip->si_band);
194                                 break;
195                         }
196                         break;
197 #ifdef HAVE_SIGINFO_T_SI_SYSCALL
198                 case SIGSYS:
199                         tprintf(", si_call_addr=%#lx, si_syscall=__NR_%s, si_arch=",
200                                 (unsigned long) sip->si_call_addr,
201                                 syscall_name((unsigned) sip->si_syscall));
202                         printxval(audit_arch, sip->si_arch, "AUDIT_ARCH_???");
203                         break;
204 #endif
205                 default:
206                         if (sip->si_pid || sip->si_uid)
207                                 printsigsource(sip);
208                         if (sip->si_ptr)
209                                 printsigval(sip, verbose);
210                 }
211         }
212 }
213
214 #ifdef IN_MPERS
215 static
216 #endif
217 void
218 printsiginfo(const siginfo_t *sip, bool verbose)
219 {
220         if (sip->si_signo == 0) {
221                 tprints("{}");
222                 return;
223         }
224         tprints("{si_signo=");
225         printsignal(sip->si_signo);
226
227         tprints(", si_code=");
228         print_si_code(sip->si_signo, sip->si_code);
229
230 #ifdef SI_NOINFO
231         if (sip->si_code != SI_NOINFO)
232 #endif
233                 print_si_info(sip, verbose);
234
235         tprints("}");
236 }
237
238 MPERS_PRINTER_DECL(void, printsiginfo_at)(struct tcb *tcp, long addr)
239 {
240         siginfo_t si;
241
242         if (!umove_or_printaddr(tcp, addr, &si))
243                 printsiginfo(&si, verbose(tcp));
244 }