1 /* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl> 4 * Copyright (c) 1993-1996 Rick Sladkey <jrs (at) world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) cistron.nl> 6 * Copyright (c) 2001 John Hughes <john (at) Calva.COM> 7 * Copyright (c) 2013 Denys Vlasenko <vda.linux (at) googlemail.com> 8 * Copyright (c) 2011-2015 Dmitry V. Levin <ldv (at) altlinux.org> 9 * Copyright (c) 2015 Elvira Khabirova <lineprinter0 (at) gmail.com> 10 * Copyright (c) 2015-2018 The strace developers. 11 * All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. The name of the author may not be used to endorse or promote products 22 * derived from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #include "defs.h" 37 38 #include DEF_MPERS_TYPE(siginfo_t) 39 40 #include <signal.h> 41 #include <linux/audit.h> 42 43 #include MPERS_DEFS 44 45 #include "nr_prefix.c" 46 47 #ifndef IN_MPERS 48 #include "printsiginfo.h" 49 #endif 50 51 #include "xlat/audit_arch.h" 52 #include "xlat/sigbus_codes.h" 53 #include "xlat/sigchld_codes.h" 54 #include "xlat/sigfpe_codes.h" 55 #include "xlat/sigill_codes.h" 56 #include "xlat/siginfo_codes.h" 57 #include "xlat/sigpoll_codes.h" 58 #include "xlat/sigprof_codes.h" 59 #include "xlat/sigsegv_codes.h" 60 #include "xlat/sigsys_codes.h" 61 #include "xlat/sigtrap_codes.h" 62 63 #ifdef SIGEMT 64 # include "xlat/sigemt_codes.h" 65 #endif 66 67 #ifndef SI_FROMUSER 68 # define SI_FROMUSER(sip) ((sip)->si_code <= 0) 69 #endif 70 71 static void 72 printsigsource(const siginfo_t *sip) 73 { 74 tprintf(", si_pid=%u, si_uid=%u", 75 (unsigned int) sip->si_pid, 76 (unsigned int) sip->si_uid); 77 } 78 79 static void 80 printsigval(const siginfo_t *sip) 81 { 82 tprintf(", si_value={int=%d, ptr=", sip->si_int); 83 printaddr(ptr_to_kulong(sip->si_ptr)); 84 tprints("}"); 85 } 86 87 static void 88 print_si_code(int si_signo, unsigned 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) 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); 160 break; 161 #endif 162 default: 163 printsigsource(sip); 164 if (sip->si_ptr) 165 printsigval(sip); 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 tprintf(", si_utime=%llu, si_stime=%llu", 178 zero_extend_signed_to_ull(sip->si_utime), 179 zero_extend_signed_to_ull(sip->si_stime)); 180 break; 181 case SIGILL: case SIGFPE: 182 case SIGSEGV: case SIGBUS: 183 tprints(", si_addr="); 184 printaddr(ptr_to_kulong(sip->si_addr)); 185 break; 186 case SIGPOLL: 187 switch (sip->si_code) { 188 case POLL_IN: case POLL_OUT: case POLL_MSG: 189 tprintf(", si_band=%ld", 190 (long) sip->si_band); 191 break; 192 } 193 break; 194 #ifdef HAVE_SIGINFO_T_SI_SYSCALL 195 case SIGSYS: { 196 /* 197 * Note that we can safely use the personlity set in 198 * current_personality here (and don't have to guess it 199 * based on X32_SYSCALL_BIT and si_arch, for example): 200 * - The signal is delivered as a result of seccomp 201 * filtering to the process executing forbidden 202 * syscall. 203 * - We have set the personality for the tracee during 204 * the syscall entering. 205 * - The current_personality is reliably switched in 206 * the next_event routine, it is set to the 207 * personality of the last call made (the one that 208 * triggered the signal delivery). 209 * - Looks like there are no other cases where SIGSYS 210 * is delivered from the kernel so far. 211 */ 212 const char *scname = syscall_name(shuffle_scno( 213 (unsigned) sip->si_syscall)); 214 215 tprints(", si_call_addr="); 216 printaddr(ptr_to_kulong(sip->si_call_addr)); 217 tprints(", si_syscall="); 218 if (scname) 219 tprintf("%s%s", 220 nr_prefix(sip->si_syscall), scname); 221 else 222 tprintf("%u", (unsigned) sip->si_syscall); 223 tprints(", si_arch="); 224 printxval(audit_arch, sip->si_arch, "AUDIT_ARCH_???"); 225 break; 226 } 227 #endif 228 default: 229 if (sip->si_pid || sip->si_uid) 230 printsigsource(sip); 231 if (sip->si_ptr) 232 printsigval(sip); 233 } 234 } 235 } 236 237 #ifdef IN_MPERS 238 static 239 #endif 240 void 241 printsiginfo(const siginfo_t *sip) 242 { 243 if (sip->si_signo == 0) { 244 tprints("{}"); 245 return; 246 } 247 tprints("{si_signo="); 248 printsignal(sip->si_signo); 249 250 tprints(", si_code="); 251 print_si_code(sip->si_signo, sip->si_code); 252 253 #ifdef SI_NOINFO 254 if (sip->si_code != SI_NOINFO) 255 #endif 256 print_si_info(sip); 257 258 tprints("}"); 259 } 260 261 MPERS_PRINTER_DECL(void, printsiginfo_at, 262 struct tcb *const tcp, const kernel_ulong_t addr) 263 { 264 siginfo_t si; 265 266 if (!umove_or_printaddr(tcp, addr, &si)) 267 printsiginfo(&si); 268 } 269 270 static bool 271 print_siginfo_t(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data) 272 { 273 printsiginfo((const siginfo_t *) elem_buf); 274 return true; 275 } 276 277 MPERS_PRINTER_DECL(void, print_siginfo_array, struct tcb *const tcp, 278 const kernel_ulong_t addr, const kernel_ulong_t len) 279 { 280 siginfo_t si; 281 282 print_array(tcp, addr, len, &si, sizeof(si), 283 umoven_or_printaddr, print_siginfo_t, 0); 284 } 285