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 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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_data struct_user_offsets_data[] = {
  31. #include "userent.h"
  32. { 0, 0 }
  33. };
  34. static const struct xlat struct_user_offsets = {
  35. .type = XT_SORTED,
  36. .size = ARRAY_SIZE(struct_user_offsets_data) - 1,
  37. .data = struct_user_offsets_data,
  38. };
  39. static void
  40. print_user_offset_addr(const kernel_ulong_t addr)
  41. {
  42. const uint64_t last_user_offset = struct_user_offsets.size ?
  43. struct_user_offsets.data[struct_user_offsets.size - 1].val : 0;
  44. uint64_t base_addr = addr;
  45. const char *str = xlookup_le(&struct_user_offsets, &base_addr);
  46. /* We don't want to pretty print addresses beyond struct user */
  47. if (addr > base_addr && base_addr == last_user_offset)
  48. str = NULL;
  49. if (!str || xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
  50. printaddr(addr);
  51. if (!str || xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
  52. return;
  53. if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
  54. tprints(" /* ");
  55. if (base_addr == addr)
  56. tprints(str);
  57. else
  58. tprintf("%s + %" PRI_klu,
  59. str, addr - (kernel_ulong_t) base_addr);
  60. if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
  61. tprints(" */");
  62. }
  63. SYS_FUNC(ptrace)
  64. {
  65. const kernel_ulong_t request = tcp->u_arg[0];
  66. const int pid = tcp->u_arg[1];
  67. const kernel_ulong_t addr = tcp->u_arg[2];
  68. const kernel_ulong_t data = tcp->u_arg[3];
  69. if (entering(tcp)) {
  70. /* request */
  71. printxval64(ptrace_cmds, request, "PTRACE_???");
  72. if (request == PTRACE_TRACEME) {
  73. /* pid, addr, and data are ignored. */
  74. return RVAL_DECODED;
  75. }
  76. /* pid */
  77. tprintf(", %d", pid);
  78. /* addr */
  79. switch (request) {
  80. case PTRACE_ATTACH:
  81. case PTRACE_INTERRUPT:
  82. case PTRACE_KILL:
  83. case PTRACE_LISTEN:
  84. /* addr and data are ignored */
  85. return RVAL_DECODED;
  86. case PTRACE_PEEKUSER:
  87. case PTRACE_POKEUSER:
  88. tprints(", ");
  89. print_user_offset_addr(addr);
  90. break;
  91. case PTRACE_GETREGSET:
  92. case PTRACE_SETREGSET:
  93. tprints(", ");
  94. printxval(nt_descriptor_types, addr, "NT_???");
  95. break;
  96. case PTRACE_GETSIGMASK:
  97. case PTRACE_SETSIGMASK:
  98. case PTRACE_SECCOMP_GET_FILTER:
  99. case PTRACE_SECCOMP_GET_METADATA:
  100. case PTRACE_GET_SYSCALL_INFO:
  101. tprintf(", %" PRI_klu, addr);
  102. break;
  103. case PTRACE_PEEKSIGINFO: {
  104. tprints(", ");
  105. struct {
  106. uint64_t off;
  107. uint32_t flags;
  108. uint32_t nr;
  109. } psi;
  110. if (umove_or_printaddr(tcp, addr, &psi)) {
  111. tprints(", ");
  112. printaddr(data);
  113. return RVAL_DECODED;
  114. }
  115. tprintf("{off=%" PRIu64 ", flags=", psi.off);
  116. printflags(ptrace_peeksiginfo_flags, psi.flags,
  117. "PTRACE_PEEKSIGINFO_???");
  118. tprintf(", nr=%u}", psi.nr);
  119. break;
  120. }
  121. default:
  122. tprints(", ");
  123. printaddr(addr);
  124. }
  125. #if defined IA64 || defined SPARC || defined SPARC64
  126. switch (request) {
  127. # ifdef IA64
  128. case PTRACE_PEEKDATA:
  129. case PTRACE_PEEKTEXT:
  130. case PTRACE_PEEKUSER:
  131. /* data is ignored */
  132. return RVAL_DECODED | RVAL_HEX;
  133. # endif /* IA64 */
  134. # if defined SPARC || defined SPARC64
  135. case PTRACE_GETREGS:
  136. case PTRACE_SETREGS:
  137. case PTRACE_GETFPREGS:
  138. case PTRACE_SETFPREGS:
  139. /* data is ignored */
  140. return RVAL_DECODED;
  141. # endif /* SPARC || SPARC64 */
  142. }
  143. #endif /* IA64 || SPARC || SPARC64 */
  144. tprints(", ");
  145. /* data */
  146. switch (request) {
  147. case PTRACE_CONT:
  148. case PTRACE_DETACH:
  149. case PTRACE_SYSCALL:
  150. #ifdef PTRACE_SINGLESTEP
  151. case PTRACE_SINGLESTEP:
  152. #endif
  153. #ifdef PTRACE_SINGLEBLOCK
  154. case PTRACE_SINGLEBLOCK:
  155. #endif
  156. #ifdef PTRACE_SYSEMU
  157. case PTRACE_SYSEMU:
  158. #endif
  159. #ifdef PTRACE_SYSEMU_SINGLESTEP
  160. case PTRACE_SYSEMU_SINGLESTEP:
  161. #endif
  162. printsignal(data);
  163. break;
  164. case PTRACE_SEIZE:
  165. case PTRACE_SETOPTIONS:
  166. #ifdef PTRACE_OLDSETOPTIONS
  167. case PTRACE_OLDSETOPTIONS:
  168. #endif
  169. printflags64(ptrace_setoptions_flags, data, "PTRACE_O_???");
  170. break;
  171. case PTRACE_SETSIGINFO:
  172. printsiginfo_at(tcp, data);
  173. break;
  174. case PTRACE_SETSIGMASK:
  175. print_sigset_addr_len(tcp, data, addr);
  176. break;
  177. case PTRACE_SETREGSET:
  178. tprint_iov(tcp, /*len:*/ 1, data, IOV_DECODE_ADDR);
  179. break;
  180. case PTRACE_SECCOMP_GET_METADATA:
  181. if (verbose(tcp)) {
  182. uint64_t filter_off;
  183. if (addr < sizeof(filter_off) ||
  184. umove(tcp, data, &filter_off)) {
  185. printaddr(data);
  186. return RVAL_DECODED;
  187. }
  188. tprintf("{filter_off=%" PRIu64, filter_off);
  189. return 0;
  190. }
  191. printaddr(data);
  192. break;
  193. #ifndef IA64
  194. case PTRACE_PEEKDATA:
  195. case PTRACE_PEEKTEXT:
  196. case PTRACE_PEEKUSER:
  197. #endif
  198. case PTRACE_GETEVENTMSG:
  199. case PTRACE_GETREGSET:
  200. case PTRACE_GETSIGINFO:
  201. case PTRACE_GETSIGMASK:
  202. case PTRACE_PEEKSIGINFO:
  203. case PTRACE_SECCOMP_GET_FILTER:
  204. case PTRACE_GET_SYSCALL_INFO:
  205. if (verbose(tcp)) {
  206. /* print data on exiting syscall */
  207. return 0;
  208. }
  209. ATTRIBUTE_FALLTHROUGH;
  210. default:
  211. printaddr(data);
  212. break;
  213. }
  214. return RVAL_DECODED;
  215. } else {
  216. switch (request) {
  217. #ifndef IA64
  218. case PTRACE_PEEKDATA:
  219. case PTRACE_PEEKTEXT:
  220. case PTRACE_PEEKUSER:
  221. printnum_ptr(tcp, data);
  222. break;
  223. #endif
  224. case PTRACE_GETEVENTMSG:
  225. printnum_ulong(tcp, data);
  226. break;
  227. case PTRACE_GETREGSET:
  228. tprint_iov(tcp, /*len:*/ 1, data, IOV_DECODE_ADDR);
  229. break;
  230. case PTRACE_GETSIGINFO:
  231. printsiginfo_at(tcp, data);
  232. break;
  233. case PTRACE_GETSIGMASK:
  234. print_sigset_addr_len(tcp, data, addr);
  235. break;
  236. case PTRACE_PEEKSIGINFO:
  237. print_siginfo_array(tcp, data, tcp->u_rval);
  238. break;
  239. case PTRACE_SECCOMP_GET_FILTER:
  240. print_seccomp_fprog(tcp, data, tcp->u_rval);
  241. break;
  242. case PTRACE_SECCOMP_GET_METADATA: {
  243. const size_t offset = sizeof(uint64_t);
  244. uint64_t flags = 0;
  245. size_t ret_size = MIN((kernel_ulong_t) tcp->u_rval,
  246. offset + sizeof(flags));
  247. if (syserror(tcp) || ret_size <= offset) {
  248. tprints("}");
  249. return 0;
  250. }
  251. if (umoven(tcp, data + offset, ret_size - offset,
  252. &flags)) {
  253. tprints(", ...}");
  254. return 0;
  255. }
  256. tprints(", flags=");
  257. printflags64(seccomp_filter_flags, flags,
  258. "SECCOMP_FILTER_FLAG_???");
  259. if ((kernel_ulong_t) tcp->u_rval > ret_size)
  260. tprints(", ...");
  261. tprints("}");
  262. break;
  263. }
  264. case PTRACE_GET_SYSCALL_INFO:
  265. print_ptrace_syscall_info(tcp, data, addr);
  266. break;
  267. }
  268. }
  269. return 0;
  270. }