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.

process.c 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  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, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
  5. * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
  6. * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  7. * Linux for s390 port by D.J. Barrow
  8. * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
  9. * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH
  10. * port by Greg Banks <gbanks@pocketpenguins.com>
  11. * Copyright (c) 1999-2018 The strace developers.
  12. *
  13. * All rights reserved.
  14. *
  15. * SPDX-License-Identifier: LGPL-2.1-or-later
  16. */
  17. #include "defs.h"
  18. #ifdef HAVE_ELF_H
  19. # include <elf.h>
  20. #endif
  21. #include "ptrace.h"
  22. #include "ptrace_syscall_info.h"
  23. #include "regs.h"
  24. #include "xlat/nt_descriptor_types.h"
  25. #include "xlat/ptrace_cmds.h"
  26. #include "xlat/ptrace_setoptions_flags.h"
  27. #include "xlat/ptrace_peeksiginfo_flags.h"
  28. #define uoff(member) offsetof(struct user, member)
  29. #define XLAT_UOFF(member) { uoff(member), "offsetof(struct user, " #member ")" }
  30. static const struct xlat struct_user_offsets[] = {
  31. #include "userent.h"
  32. XLAT_END
  33. };
  34. static void
  35. print_user_offset_addr(const kernel_ulong_t addr)
  36. {
  37. bool no_str = false;
  38. const struct xlat *x;
  39. for (x = struct_user_offsets; x->str; ++x) {
  40. if (x->val >= addr)
  41. break;
  42. }
  43. if (!x->str || (x == struct_user_offsets && x->val > addr))
  44. no_str = true;
  45. if (no_str || xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
  46. printaddr(addr);
  47. if (no_str || xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
  48. return;
  49. if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
  50. tprints(" /* ");
  51. if (x->val > addr) {
  52. --x;
  53. tprintf("%s + %" PRI_klu,
  54. x->str, addr - (kernel_ulong_t) x->val);
  55. } else {
  56. tprints(x->str);
  57. }
  58. if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
  59. tprints(" */");
  60. }
  61. SYS_FUNC(ptrace)
  62. {
  63. const kernel_ulong_t request = tcp->u_arg[0];
  64. const int pid = tcp->u_arg[1];
  65. const kernel_ulong_t addr = tcp->u_arg[2];
  66. const kernel_ulong_t data = tcp->u_arg[3];
  67. if (entering(tcp)) {
  68. /* request */
  69. printxval64(ptrace_cmds, request, "PTRACE_???");
  70. if (request == PTRACE_TRACEME) {
  71. /* pid, addr, and data are ignored. */
  72. return RVAL_DECODED;
  73. }
  74. /* pid */
  75. tprintf(", %d", pid);
  76. /* addr */
  77. switch (request) {
  78. case PTRACE_ATTACH:
  79. case PTRACE_INTERRUPT:
  80. case PTRACE_KILL:
  81. case PTRACE_LISTEN:
  82. /* addr and data are ignored */
  83. return RVAL_DECODED;
  84. case PTRACE_PEEKUSER:
  85. case PTRACE_POKEUSER:
  86. tprints(", ");
  87. print_user_offset_addr(addr);
  88. break;
  89. case PTRACE_GETREGSET:
  90. case PTRACE_SETREGSET:
  91. tprints(", ");
  92. printxval(nt_descriptor_types, addr, "NT_???");
  93. break;
  94. case PTRACE_GETSIGMASK:
  95. case PTRACE_SETSIGMASK:
  96. case PTRACE_SECCOMP_GET_FILTER:
  97. case PTRACE_SECCOMP_GET_METADATA:
  98. case PTRACE_GET_SYSCALL_INFO:
  99. tprintf(", %" PRI_klu, addr);
  100. break;
  101. case PTRACE_PEEKSIGINFO: {
  102. tprints(", ");
  103. struct {
  104. uint64_t off;
  105. uint32_t flags;
  106. uint32_t nr;
  107. } psi;
  108. if (umove_or_printaddr(tcp, addr, &psi)) {
  109. tprints(", ");
  110. printaddr(data);
  111. return RVAL_DECODED;
  112. }
  113. tprintf("{off=%" PRIu64 ", flags=", psi.off);
  114. printflags(ptrace_peeksiginfo_flags, psi.flags,
  115. "PTRACE_PEEKSIGINFO_???");
  116. tprintf(", nr=%u}", psi.nr);
  117. break;
  118. }
  119. default:
  120. tprints(", ");
  121. printaddr(addr);
  122. }
  123. #if defined IA64 || defined SPARC || defined SPARC64
  124. switch (request) {
  125. # ifdef IA64
  126. case PTRACE_PEEKDATA:
  127. case PTRACE_PEEKTEXT:
  128. case PTRACE_PEEKUSER:
  129. /* data is ignored */
  130. return RVAL_DECODED | RVAL_HEX;
  131. # endif /* IA64 */
  132. # if defined SPARC || defined SPARC64
  133. case PTRACE_GETREGS:
  134. case PTRACE_SETREGS:
  135. case PTRACE_GETFPREGS:
  136. case PTRACE_SETFPREGS:
  137. /* data is ignored */
  138. return RVAL_DECODED;
  139. # endif /* SPARC || SPARC64 */
  140. }
  141. #endif /* IA64 || SPARC || SPARC64 */
  142. tprints(", ");
  143. /* data */
  144. switch (request) {
  145. case PTRACE_CONT:
  146. case PTRACE_DETACH:
  147. case PTRACE_SYSCALL:
  148. #ifdef PTRACE_SINGLESTEP
  149. case PTRACE_SINGLESTEP:
  150. #endif
  151. #ifdef PTRACE_SINGLEBLOCK
  152. case PTRACE_SINGLEBLOCK:
  153. #endif
  154. #ifdef PTRACE_SYSEMU
  155. case PTRACE_SYSEMU:
  156. #endif
  157. #ifdef PTRACE_SYSEMU_SINGLESTEP
  158. case PTRACE_SYSEMU_SINGLESTEP:
  159. #endif
  160. printsignal(data);
  161. break;
  162. case PTRACE_SEIZE:
  163. case PTRACE_SETOPTIONS:
  164. #ifdef PTRACE_OLDSETOPTIONS
  165. case PTRACE_OLDSETOPTIONS:
  166. #endif
  167. printflags64(ptrace_setoptions_flags, data, "PTRACE_O_???");
  168. break;
  169. case PTRACE_SETSIGINFO:
  170. printsiginfo_at(tcp, data);
  171. break;
  172. case PTRACE_SETSIGMASK:
  173. print_sigset_addr_len(tcp, data, addr);
  174. break;
  175. case PTRACE_SETREGSET:
  176. tprint_iov(tcp, /*len:*/ 1, data, IOV_DECODE_ADDR);
  177. break;
  178. case PTRACE_SECCOMP_GET_METADATA:
  179. if (verbose(tcp)) {
  180. uint64_t filter_off;
  181. if (addr < sizeof(filter_off) ||
  182. umove(tcp, data, &filter_off)) {
  183. printaddr(data);
  184. return RVAL_DECODED;
  185. }
  186. tprintf("{filter_off=%" PRIu64, filter_off);
  187. return 0;
  188. }
  189. printaddr(data);
  190. break;
  191. #ifndef IA64
  192. case PTRACE_PEEKDATA:
  193. case PTRACE_PEEKTEXT:
  194. case PTRACE_PEEKUSER:
  195. #endif
  196. case PTRACE_GETEVENTMSG:
  197. case PTRACE_GETREGSET:
  198. case PTRACE_GETSIGINFO:
  199. case PTRACE_GETSIGMASK:
  200. case PTRACE_PEEKSIGINFO:
  201. case PTRACE_SECCOMP_GET_FILTER:
  202. case PTRACE_GET_SYSCALL_INFO:
  203. if (verbose(tcp)) {
  204. /* print data on exiting syscall */
  205. return 0;
  206. }
  207. ATTRIBUTE_FALLTHROUGH;
  208. default:
  209. printaddr(data);
  210. break;
  211. }
  212. return RVAL_DECODED;
  213. } else {
  214. switch (request) {
  215. #ifndef IA64
  216. case PTRACE_PEEKDATA:
  217. case PTRACE_PEEKTEXT:
  218. case PTRACE_PEEKUSER:
  219. printnum_ptr(tcp, data);
  220. break;
  221. #endif
  222. case PTRACE_GETEVENTMSG:
  223. printnum_ulong(tcp, data);
  224. break;
  225. case PTRACE_GETREGSET:
  226. tprint_iov(tcp, /*len:*/ 1, data, IOV_DECODE_ADDR);
  227. break;
  228. case PTRACE_GETSIGINFO:
  229. printsiginfo_at(tcp, data);
  230. break;
  231. case PTRACE_GETSIGMASK:
  232. print_sigset_addr_len(tcp, data, addr);
  233. break;
  234. case PTRACE_PEEKSIGINFO:
  235. print_siginfo_array(tcp, data, tcp->u_rval);
  236. break;
  237. case PTRACE_SECCOMP_GET_FILTER:
  238. print_seccomp_fprog(tcp, data, tcp->u_rval);
  239. break;
  240. case PTRACE_SECCOMP_GET_METADATA: {
  241. const size_t offset = sizeof(uint64_t);
  242. uint64_t flags = 0;
  243. size_t ret_size = MIN((kernel_ulong_t) tcp->u_rval,
  244. offset + sizeof(flags));
  245. if (syserror(tcp) || ret_size <= offset) {
  246. tprints("}");
  247. return 0;
  248. }
  249. if (umoven(tcp, data + offset, ret_size - offset,
  250. &flags)) {
  251. tprints(", ...}");
  252. return 0;
  253. }
  254. tprints(", flags=");
  255. printflags64(seccomp_filter_flags, flags,
  256. "SECCOMP_FILTER_FLAG_???");
  257. if ((kernel_ulong_t) tcp->u_rval > ret_size)
  258. tprints(", ...");
  259. tprints("}");
  260. break;
  261. }
  262. case PTRACE_GET_SYSCALL_INFO:
  263. print_ptrace_syscall_info(tcp, data, addr);
  264. break;
  265. }
  266. }
  267. return 0;
  268. }