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.

tracing_backend.h 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. /*
  2. * Tracing backend interface header.
  3. *
  4. * Copyright (c) 2017-2019 The strace developers.
  5. * All rights reserved.
  6. *
  7. * SPDX-License-Identifier: LGPL-2.1-or-later
  8. */
  9. #ifndef STRACE_TRACING_BACKEND_H
  10. #define STRACE_TRACING_BACKEND_H
  11. #include "defs.h"
  12. #include "trace_event.h"
  13. #if defined IN_MPERS || defined IN_MPERS_BOOTSTRAP
  14. typedef int strace_stat_t;
  15. #else
  16. # include "largefile_wrappers.h"
  17. strace_stat_t;
  18. #endif
  19. #if ADDITIONAL_TRACING_BACKENDS
  20. struct msghdr;
  21. /**
  22. * Structure with pointers to functions (and some other data) that are specific
  23. * to a tracing backend. Tracing backend is currently assumed to be more or less
  24. * ptrace-like, as a result, it has some peculiarities.
  25. */
  26. struct tracing_backend {
  27. const char *name;
  28. /* Initialisation and cleanup routines */
  29. /** Parse tracing-backend-specific argument */
  30. bool (*handle_arg) (char arg, char *optarg);
  31. /** Initialisation of the tracing backend */
  32. bool (*init) (int argc, char *argv[]);
  33. /** Optional. Called at the final initialisation stage, after attach */
  34. void (*post_init) (void);
  35. /** Optional. Called at the end of strace.c:cleanup(). */
  36. void (*cleanup) (int sig);
  37. /* XXX Merge these two in start_init */
  38. bool (*prog_pid_check) (char *exec_name, int nprocs);
  39. bool (*verify_args) (const char *username, bool daemon,
  40. unsigned int *follow_fork);
  41. /* Tracee creation/reaping and attaching/detaching */
  42. void (*startup_child) (char **argv, char **env);
  43. void (*attach_tcb) (struct tcb *tcp);
  44. void (*detach) (struct tcb *tcp);
  45. int (*kill) (struct tcb *tcp, int sig);
  46. /* Tracing loop data manipulation. */
  47. size_t trace_wait_data_size;
  48. struct tcb_wait_data * (*init_trace_wait_data) (void *p);
  49. struct tcb_wait_data * (*copy_trace_wait_data) (struct
  50. tcb_wait_data *wd);
  51. void (*free_trace_wait_data) (struct tcb_wait_data *wd);
  52. /* Functions related to the main tracing loop. */
  53. /** Return new event */
  54. struct tcb_wait_data * (*next_event) (void);
  55. /** Additional handling for TE_STOP_BEFORE_EXECVE */
  56. void (*handle_exec) (struct tcb **current_tcp,
  57. struct tcb_wait_data *wd);
  58. /** Restart process after successful processing */
  59. bool (*restart_process)(struct tcb *tcp, struct tcb_wait_data *wd);
  60. /* Tracee's memory/register/metadata manipulation routines */
  61. void (*clear_regs) (struct tcb *tcp);
  62. long (*get_regs) (struct tcb * const tcp);
  63. int (*get_scno) (struct tcb *tcp);
  64. int (*set_scno) (struct tcb *tcp, kernel_ulong_t scno);
  65. /** Set tracee's error code in accordance with tcb's data */
  66. void (*set_error) (struct tcb *tcp, unsigned long new_error);
  67. /** Set tracee's return code in accordance with tcb's data */
  68. void (*set_success) (struct tcb *tcp, kernel_long_t new_rval);
  69. bool (*get_instruction_pointer) (struct tcb *tcp, kernel_ulong_t *ip);
  70. bool (*get_stack_pointer)(struct tcb *tcp, kernel_ulong_t *sp);
  71. int (*get_syscall_args) (struct tcb *tcp);
  72. int (*get_syscall_result) (struct tcb *tcp);
  73. int (*umoven) (struct tcb *const tcp, kernel_ulong_t addr,
  74. unsigned int len, void *const our_addr);
  75. int (*umovestr) (struct tcb *const tcp, kernel_ulong_t addr,
  76. unsigned int len, char *laddr);
  77. int (*upeek) (struct tcb *tcp, unsigned long off, kernel_ulong_t *res);
  78. int (*upoke) (struct tcb *tcp, unsigned long off, kernel_ulong_t val);
  79. /*
  80. * File I/O
  81. *
  82. * As of now, these functions are deemed to be executed in the context
  83. * (namespace) of the tracer on the target machine and not
  84. * in the context (namespace) of the specific tracee.
  85. */
  86. /**
  87. * Resolve a path.
  88. * Optional (can be implemented via open+readlink+close).
  89. * Used by: pathtrace_select_set.
  90. */
  91. char * (*realpath) (struct tcb *tcp, const char *path,
  92. char *resolved_path);
  93. /**
  94. * Open a file.
  95. * Used by: read_int_from_file, realpath.
  96. */
  97. int (*open) (struct tcb *tcp, const char *path, int flags, int mode);
  98. /**
  99. * Read from file, with interface similar to pread(2).
  100. * Used by: read_int_from_file.
  101. */
  102. ssize_t (*pread) (struct tcb *tcp, int fd, void *buf, size_t count,
  103. off_t offset);
  104. /**
  105. * Close file.
  106. * Used by: read_int_from_file, realpath.
  107. */
  108. int (*close) (struct tcb *tcp, int fd);
  109. /**
  110. * Read symlink contents.
  111. * Used by: getfdpath, realpath.
  112. */
  113. ssize_t (*readlink) (struct tcb *tcp, const char *path, char *buf,
  114. size_t buf_size);
  115. /**
  116. * Get file status.
  117. * Optional. Used by: printdev
  118. */
  119. int (*stat) (struct tcb *tcp, const char *path, strace_stat_t *buf);
  120. /**
  121. * Get file status.
  122. * Optional. Used by: tracee_stat
  123. */
  124. int (*fstat) (struct tcb *tcp, int fd, strace_stat_t *buf);
  125. /**
  126. * Get extended attributes of a file.
  127. * Optional. Used by: getfdproto.
  128. */
  129. ssize_t (*getxattr) (struct tcb *tcp, const char *path,
  130. const char *name, void *buf, size_t buf_size);
  131. /**
  132. * Create a socket.
  133. * Optional. Used by: get_sockaddr_by_inode_uncached,
  134. * genl_families_xlat.
  135. */
  136. int (*socket) (struct tcb *tcp, int domain, int type, int protocol);
  137. /**
  138. * Send a message via socket.
  139. * Optional. Used by: send_query
  140. * It's tracing backend responsibility to convert struct msghdr fields
  141. * to tracee's format and back, it should be a drop-in replacement
  142. * for users. Users, however, are responsible for proper generation
  143. * of message data in target's format. */
  144. ssize_t (*sendmsg) (struct tcb *tcp, int fd, const struct msghdr *msg,
  145. int flags);
  146. /**
  147. * Receive a message via socket.
  148. * Optional. Used by: receive_response
  149. * It's tracing backend responsibility to convert struct msghdr fields
  150. * to tracee's format and back, it should be a drop-in replacement
  151. * for users. Users, however, are responsible for proper interpretation
  152. * of message data as provided in target's format. */
  153. ssize_t (*recvmsg) (struct tcb *tcp, int fd, struct msghdr *msg,
  154. int flags);
  155. };
  156. /* Tracing backend management interface. */
  157. extern const struct tracing_backend *cur_tracing_backend;
  158. extern void set_tracing_backend(struct tracing_backend *backend);
  159. /**
  160. * Fallback handler for tracing backends that implement fstat, but no stat.
  161. */
  162. extern int tracing_backend_stat_via_fstat(struct tcb *tcp, const char *path,
  163. strace_stat_t *buf);
  164. /* I/O function wrappers for tracing backends that are run on the same system */
  165. extern int local_kill(struct tcb *tcp, int sig);
  166. extern char *local_realpath(struct tcb *tcp, const char *path,
  167. char *resolved_path);
  168. extern int local_open(struct tcb *tcp, const char *path, int flags, int mode);
  169. extern ssize_t local_pread(struct tcb *tcp, int fd, void *buf, size_t count,
  170. off_t offset);
  171. extern int local_close(struct tcb *tcp, int fd);
  172. extern ssize_t local_readlink(struct tcb *tcp, const char *path, char *buf,
  173. size_t buf_size);
  174. extern int local_stat(struct tcb *tcp, const char *path, strace_stat_t *buf);
  175. extern int local_fstat(struct tcb *tcp, int fd, strace_stat_t *buf);
  176. extern ssize_t local_getxattr(struct tcb *tcp, const char *path,
  177. const char *name, void *buf, size_t buf_size);
  178. extern int local_socket(struct tcb *tcp, int domain, int type, int protocol);
  179. extern ssize_t local_sendmsg(struct tcb *tcp, int fd, const struct msghdr *msg,
  180. int flags);
  181. extern ssize_t local_recvmsg(struct tcb *tcp, int fd, struct msghdr *msg,
  182. int flags);
  183. /* Wrappers for tracing-backend-specific calls. */
  184. static inline const char *
  185. tracing_backend_name(void)
  186. {
  187. return cur_tracing_backend->name;
  188. }
  189. static inline bool
  190. tracing_backend_handle_arg(char arg, char *optarg)
  191. {
  192. if (cur_tracing_backend->handle_arg)
  193. return cur_tracing_backend->handle_arg(arg, optarg);
  194. return false;
  195. }
  196. static inline bool
  197. tracing_backend_init(int argc, char *argv[])
  198. {
  199. if (cur_tracing_backend->init)
  200. return cur_tracing_backend->init(argc, argv);
  201. return true;
  202. }
  203. static inline void
  204. tracing_backend_post_init(void)
  205. {
  206. if (cur_tracing_backend->post_init)
  207. cur_tracing_backend->post_init();
  208. }
  209. static inline void
  210. tracing_backend_cleanup(int sig)
  211. {
  212. if (cur_tracing_backend->cleanup)
  213. cur_tracing_backend->cleanup(sig);
  214. }
  215. static inline void
  216. startup_child(char **argv, char **env)
  217. {
  218. if (cur_tracing_backend->startup_child)
  219. cur_tracing_backend->startup_child(argv, env);
  220. }
  221. static inline void
  222. attach_tcb(struct tcb *const tcp)
  223. {
  224. if (cur_tracing_backend->attach_tcb)
  225. cur_tracing_backend->attach_tcb(tcp);
  226. }
  227. static inline void
  228. detach(struct tcb *tcp)
  229. {
  230. if (cur_tracing_backend->detach)
  231. cur_tracing_backend->detach(tcp);
  232. }
  233. /*
  234. * trace_wait_data_size, init_trace_wait_data, copy_trace_wait_data,
  235. * and free_trace_wait_data shorthands are defined int tcb_wait_data.h.
  236. */
  237. static inline struct tcb_wait_data *
  238. next_event(void)
  239. {
  240. return cur_tracing_backend->next_event();
  241. }
  242. static inline void
  243. handle_exec(struct tcb **current_tcp, struct tcb_wait_data *wd)
  244. {
  245. if (cur_tracing_backend->handle_exec)
  246. cur_tracing_backend->handle_exec(current_tcp, wd);
  247. }
  248. static inline bool
  249. restart_process(struct tcb *current_tcp, struct tcb_wait_data *wd)
  250. {
  251. return cur_tracing_backend->restart_process(current_tcp, wd);
  252. }
  253. static inline void
  254. clear_regs(struct tcb *tcp)
  255. {
  256. cur_tracing_backend->clear_regs(tcp);
  257. }
  258. static inline long
  259. get_regs(struct tcb * const tcp)
  260. {
  261. return cur_tracing_backend->get_regs(tcp);
  262. }
  263. static inline int
  264. get_scno(struct tcb *tcp)
  265. {
  266. return cur_tracing_backend->get_scno(tcp);
  267. }
  268. static inline int
  269. set_scno(struct tcb *tcp, kernel_ulong_t scno)
  270. {
  271. return cur_tracing_backend->set_scno(tcp, scno);
  272. }
  273. static inline void
  274. set_error(struct tcb *tcp, unsigned long new_error)
  275. {
  276. cur_tracing_backend->set_error(tcp, new_error);
  277. }
  278. static inline void
  279. set_success(struct tcb *tcp, kernel_long_t new_rval)
  280. {
  281. cur_tracing_backend->set_success(tcp, new_rval);
  282. }
  283. static inline bool
  284. get_instruction_pointer(struct tcb *tcp, kernel_ulong_t *ip)
  285. {
  286. return (cur_tracing_backend->get_instruction_pointer
  287. ?: generic_get_instruction_pointer)(tcp, ip);
  288. }
  289. static inline bool
  290. get_stack_pointer(struct tcb *tcp, kernel_ulong_t *sp)
  291. {
  292. return (cur_tracing_backend->get_stack_pointer
  293. ?: generic_get_stack_pointer)(tcp, sp);
  294. }
  295. static inline int
  296. get_syscall_args(struct tcb *tcp)
  297. {
  298. return cur_tracing_backend->get_syscall_args(tcp);
  299. }
  300. static inline int
  301. get_syscall_result(struct tcb *tcp)
  302. {
  303. return cur_tracing_backend->get_syscall_result(tcp);
  304. }
  305. static inline int
  306. umoven(struct tcb *tcp, kernel_ulong_t addr, unsigned int len, void *laddr)
  307. {
  308. return cur_tracing_backend->umoven(tcp, addr, len, laddr);
  309. }
  310. static inline int
  311. umovestr(struct tcb *tcp, kernel_ulong_t addr, unsigned int len, char *laddr)
  312. {
  313. return cur_tracing_backend->umovestr(tcp, addr, len, laddr);
  314. }
  315. static inline int
  316. upeek(struct tcb *tcp, unsigned long off, kernel_ulong_t *res)
  317. {
  318. return cur_tracing_backend->upeek(tcp, off, res);
  319. }
  320. static inline int
  321. upoke(struct tcb *tcp, unsigned long off, kernel_ulong_t val)
  322. {
  323. return cur_tracing_backend->upoke(tcp, off, val);
  324. }
  325. static inline int
  326. tracee_kill(struct tcb *tcp, int sig)
  327. {
  328. return cur_tracing_backend->kill(tcp, sig);
  329. }
  330. static inline char *
  331. tracee_realpath(struct tcb *tcp, const char *path, char *resolved_path)
  332. {
  333. if (cur_tracing_backend->realpath)
  334. return cur_tracing_backend->realpath(tcp, path, resolved_path);
  335. return NULL;
  336. }
  337. # define error_set_errno(err_code_) (errno = (err_code_), -1)
  338. static inline int
  339. tracee_open(struct tcb *tcp, const char *path, int flags, int mode)
  340. {
  341. return cur_tracing_backend->open(tcp, path, flags, mode);
  342. }
  343. static inline ssize_t
  344. tracee_pread(struct tcb *tcp, int fd, void *buf, size_t count, off_t offset)
  345. {
  346. return cur_tracing_backend->pread(tcp, fd, buf, count, offset);
  347. }
  348. static inline int
  349. tracee_close(struct tcb *tcp, int fd)
  350. {
  351. return cur_tracing_backend->close(tcp, fd);
  352. }
  353. static inline ssize_t
  354. tracee_readlink(struct tcb *tcp, const char *path, char *buf, size_t buf_size)
  355. {
  356. return cur_tracing_backend->readlink(tcp, path, buf, buf_size);
  357. }
  358. static inline int
  359. tracee_stat(struct tcb *tcp, const char *path, strace_stat_t *buf)
  360. {
  361. if (cur_tracing_backend->stat)
  362. return cur_tracing_backend->stat(tcp, path, buf);
  363. if (cur_tracing_backend->fstat)
  364. return tracing_backend_stat_via_fstat(tcp, path, buf);
  365. return error_set_errno(ENOSYS);
  366. }
  367. static inline int
  368. tracee_fstat(struct tcb *tcp, int fd, strace_stat_t *buf)
  369. {
  370. if (cur_tracing_backend->fstat)
  371. return cur_tracing_backend->fstat(tcp, fd, buf);
  372. return error_set_errno(ENOSYS);
  373. }
  374. static inline ssize_t
  375. tracee_getxattr(struct tcb *tcp, const char *path, const char *name, void *buf,
  376. size_t buf_size)
  377. {
  378. if (cur_tracing_backend->getxattr)
  379. return cur_tracing_backend->getxattr(tcp, path, name, buf,
  380. buf_size);
  381. return error_set_errno(ENOSYS);
  382. }
  383. static inline int
  384. tracee_socket(struct tcb *tcp, int domain, int type, int protocol)
  385. {
  386. if (cur_tracing_backend->socket)
  387. return cur_tracing_backend->socket(tcp, domain, type, protocol);
  388. return error_set_errno(ENOSYS);
  389. }
  390. static inline ssize_t
  391. tracee_sendmsg(struct tcb *tcp, int fd, const struct msghdr *msg, int flags)
  392. {
  393. if (cur_tracing_backend->sendmsg)
  394. return cur_tracing_backend->sendmsg(tcp, fd, msg, flags);
  395. return error_set_errno(ENOSYS);
  396. }
  397. static inline ssize_t
  398. tracee_recvmsg(struct tcb *tcp, int fd, struct msghdr *msg, int flags)
  399. {
  400. if (cur_tracing_backend->recvmsg)
  401. return cur_tracing_backend->recvmsg(tcp, fd, msg, flags);
  402. return error_set_errno(ENOSYS);
  403. }
  404. #else /* !ADDITIONAL_TRACING_BACKENDS */
  405. # include "ptrace_backend.h"
  406. # define tracing_backend_name() "ptrace"
  407. # define tracing_backend_handle_arg(a_, o_) false
  408. # define tracing_backend_init ptrace_init
  409. # define tracing_backend_post_init() ((void) 0)
  410. # define tracing_backend_cleanup(s_) ((void) 0)
  411. # define startup_child ptrace_startup_child
  412. # define attach_tcb ptrace_attach_tcb
  413. # define detach ptrace_detach
  414. # define next_event ptrace_next_event
  415. # define handle_group_stop ptrace_handle_group_stop
  416. # define handle_exec ptrace_handle_exec
  417. # define restart_process ptrace_restart_process
  418. # define clear_regs ptrace_clear_regs
  419. # define get_regs ptrace_get_regs
  420. # define get_scno ptrace_get_scno
  421. # define set_scno ptrace_set_scno
  422. # define set_error ptrace_set_error
  423. # define set_success ptrace_set_success
  424. # define get_instruction_pointer ptrace_get_instruction_pointer
  425. # define get_stack_pointer ptrace_get_stack_pointer
  426. # define get_syscall_args ptrace_get_syscall_args
  427. # define get_syscall_result ptrace_get_syscall_result
  428. # define umoven ptrace_umoven
  429. # define umovestr ptrace_umovestr
  430. # define upeek ptrace_upeek
  431. # define upoke ptrace_upoke
  432. # define tracee_kill(tcp_, sig_) \
  433. kill((tcp_)->pid, (sig_))
  434. # define tracee_realpath(tcp_, path_, resolved_path_) \
  435. realpath((path_), (resolved_path_))
  436. # define tracee_open(tcp_, path_, flags_, mode_) \
  437. open_file((path_), (flags_), (mode_))
  438. # define tracee_pread(tcp_, fd_, buf_, count_, offset_) \
  439. pread((fd_), (buf_), (count_), (offset_))
  440. # define tracee_close(tcp_, fd_) \
  441. close(fd_)
  442. # define tracee_readlink(tcp_, path_, buf_, buf_size_) \
  443. readlink((path_), (buf_), (buf_size_))
  444. # define tracee_stat(tcp_, path_, buf_) \
  445. stat_file((path_), (buf_))
  446. # define tracee_fstat(tcp_, fd_, buf_) \
  447. fstat_file((fd_), (buf_))
  448. # define tracee_getxattr(tcp_, path_, name_, buf_, buf_size_) \
  449. getxattr((path_), (name_), (buf_), (buf_size_))
  450. # define tracee_socket(tcp_, domain_, type_, protocol_) \
  451. socket((domain_), (type_), (protocol_))
  452. # define tracee_sendmsg(tcp_, fd_, msg_, flags_) \
  453. sendmsg((fd_), (msg_), (flags_))
  454. # define tracee_recvmsg(tcp_, fd_, msg_, flags_) \
  455. recvmsg((fd_), (msg_), (flags_))
  456. #endif /* !ADDITIONAL_TRACING_BACKENDS */
  457. #endif /* !STRACE_TRACING_BACKEND_H */