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, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) cistron.nl> 6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Linux for s390 port by D.J. Barrow 8 * <barrow_dj (at) mail.yahoo.com,djbarrow (at) de.ibm.com> 9 * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH 10 * port by Greg Banks <gbanks (at) pocketpenguins.com> 11 * Copyright (c) 1999-2018 The strace developers. 12 * 13 * All rights reserved. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 18 * 1. Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in the 22 * documentation and/or other materials provided with the distribution. 23 * 3. The name of the author may not be used to endorse or promote products 24 * derived from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #include "defs.h" 39 40 #ifdef HAVE_ELF_H 41 # include <elf.h> 42 #endif 43 44 #include "ptrace.h" 45 #include "regs.h" 46 47 #include "xlat/nt_descriptor_types.h" 48 #include "xlat/ptrace_cmds.h" 49 #include "xlat/ptrace_setoptions_flags.h" 50 #include "xlat/ptrace_peeksiginfo_flags.h" 51 52 #define uoff(member) offsetof(struct user, member) 53 #define XLAT_UOFF(member) { uoff(member), "offsetof(struct user, " #member ")" } 54 55 static const struct xlat struct_user_offsets[] = { 56 #include "userent.h" 57 XLAT_END 58 }; 59 60 static void 61 print_user_offset_addr(const kernel_ulong_t addr) 62 { 63 const struct xlat *x; 64 65 for (x = struct_user_offsets; x->str; ++x) { 66 if (x->val >= addr) 67 break; 68 } 69 70 if (!x->str) { 71 printaddr(addr); 72 } else if (x->val > addr) { 73 if (x == struct_user_offsets) { 74 printaddr(addr); 75 } else { 76 --x; 77 tprintf("%s + %" PRI_klu, 78 x->str, addr - (kernel_ulong_t) x->val); 79 } 80 } else { 81 tprints(x->str); 82 } 83 } 84 85 SYS_FUNC(ptrace) 86 { 87 const kernel_ulong_t request = tcp->u_arg[0]; 88 const int pid = tcp->u_arg[1]; 89 const kernel_ulong_t addr = tcp->u_arg[2]; 90 const kernel_ulong_t data = tcp->u_arg[3]; 91 92 if (entering(tcp)) { 93 /* request */ 94 printxval64(ptrace_cmds, request, "PTRACE_???"); 95 96 if (request == PTRACE_TRACEME) { 97 /* pid, addr, and data are ignored. */ 98 return RVAL_DECODED; 99 } 100 101 /* pid */ 102 tprintf(", %d", pid); 103 104 /* addr */ 105 switch (request) { 106 case PTRACE_ATTACH: 107 case PTRACE_INTERRUPT: 108 case PTRACE_KILL: 109 case PTRACE_LISTEN: 110 /* addr and data are ignored */ 111 return RVAL_DECODED; 112 case PTRACE_PEEKUSER: 113 case PTRACE_POKEUSER: 114 tprints(", "); 115 print_user_offset_addr(addr); 116 break; 117 case PTRACE_GETREGSET: 118 case PTRACE_SETREGSET: 119 tprints(", "); 120 printxval(nt_descriptor_types, addr, "NT_???"); 121 break; 122 case PTRACE_GETSIGMASK: 123 case PTRACE_SETSIGMASK: 124 case PTRACE_SECCOMP_GET_FILTER: 125 tprintf(", %" PRI_klu, addr); 126 break; 127 case PTRACE_PEEKSIGINFO: { 128 tprints(", "); 129 struct { 130 uint64_t off; 131 uint32_t flags; 132 uint32_t nr; 133 } psi; 134 if (umove_or_printaddr(tcp, addr, &psi)) { 135 tprints(", "); 136 printaddr(data); 137 return RVAL_DECODED; 138 } 139 tprintf("{off=%" PRIu64 ", flags=", psi.off); 140 printflags(ptrace_peeksiginfo_flags, psi.flags, 141 "PTRACE_PEEKSIGINFO_???"); 142 tprintf(", nr=%u}", psi.nr); 143 break; 144 } 145 default: 146 tprints(", "); 147 printaddr(addr); 148 } 149 150 # if defined IA64 || defined SPARC || defined SPARC64 151 switch (request) { 152 # ifdef IA64 153 case PTRACE_PEEKDATA: 154 case PTRACE_PEEKTEXT: 155 case PTRACE_PEEKUSER: 156 /* data is ignored */ 157 return RVAL_DECODED | RVAL_HEX; 158 # endif /* IA64 */ 159 # if defined SPARC || defined SPARC64 160 case PTRACE_GETREGS: 161 case PTRACE_SETREGS: 162 case PTRACE_GETFPREGS: 163 case PTRACE_SETFPREGS: 164 /* data is ignored */ 165 return RVAL_DECODED; 166 # endif /* SPARC || SPARC64 */ 167 } 168 # endif /* IA64 || SPARC || SPARC64 */ 169 170 tprints(", "); 171 172 /* data */ 173 switch (request) { 174 case PTRACE_CONT: 175 case PTRACE_DETACH: 176 case PTRACE_SYSCALL: 177 #ifdef PTRACE_SINGLESTEP 178 case PTRACE_SINGLESTEP: 179 #endif 180 #ifdef PTRACE_SINGLEBLOCK 181 case PTRACE_SINGLEBLOCK: 182 #endif 183 #ifdef PTRACE_SYSEMU 184 case PTRACE_SYSEMU: 185 #endif 186 #ifdef PTRACE_SYSEMU_SINGLESTEP 187 case PTRACE_SYSEMU_SINGLESTEP: 188 #endif 189 printsignal(data); 190 break; 191 case PTRACE_SEIZE: 192 case PTRACE_SETOPTIONS: 193 #ifdef PTRACE_OLDSETOPTIONS 194 case PTRACE_OLDSETOPTIONS: 195 #endif 196 printflags64(ptrace_setoptions_flags, data, "PTRACE_O_???"); 197 break; 198 case PTRACE_SETSIGINFO: 199 printsiginfo_at(tcp, data); 200 break; 201 case PTRACE_SETSIGMASK: 202 print_sigset_addr_len(tcp, data, addr); 203 break; 204 case PTRACE_SETREGSET: 205 tprint_iov(tcp, /*len:*/ 1, data, IOV_DECODE_ADDR); 206 break; 207 #ifndef IA64 208 case PTRACE_PEEKDATA: 209 case PTRACE_PEEKTEXT: 210 case PTRACE_PEEKUSER: 211 #endif 212 case PTRACE_GETEVENTMSG: 213 case PTRACE_GETREGSET: 214 case PTRACE_GETSIGINFO: 215 case PTRACE_GETSIGMASK: 216 case PTRACE_PEEKSIGINFO: 217 case PTRACE_SECCOMP_GET_FILTER: 218 if (verbose(tcp)) { 219 /* print data on exiting syscall */ 220 return 0; 221 } 222 /* fall through */ 223 default: 224 printaddr(data); 225 break; 226 } 227 228 return RVAL_DECODED; 229 } else { 230 switch (request) { 231 #ifndef IA64 232 case PTRACE_PEEKDATA: 233 case PTRACE_PEEKTEXT: 234 case PTRACE_PEEKUSER: 235 printnum_ptr(tcp, data); 236 break; 237 #endif 238 case PTRACE_GETEVENTMSG: 239 printnum_ulong(tcp, data); 240 break; 241 case PTRACE_GETREGSET: 242 tprint_iov(tcp, /*len:*/ 1, data, IOV_DECODE_ADDR); 243 break; 244 case PTRACE_GETSIGINFO: 245 printsiginfo_at(tcp, data); 246 break; 247 case PTRACE_GETSIGMASK: 248 print_sigset_addr_len(tcp, data, addr); 249 break; 250 case PTRACE_PEEKSIGINFO: 251 print_siginfo_array(tcp, data, tcp->u_rval); 252 break; 253 case PTRACE_SECCOMP_GET_FILTER: 254 print_seccomp_fprog(tcp, data, tcp->u_rval); 255 break; 256 } 257 } 258 return 0; 259 } 260