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.

msghdr.c 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  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-2000 Wichert Akkerman <wichert@cistron.nl>
  6. * Copyright (c) 2005-2016 Dmitry V. Levin <ldv@altlinux.org>
  7. * Copyright (c) 2016-2019 The strace developers.
  8. * All rights reserved.
  9. *
  10. * SPDX-License-Identifier: LGPL-2.1-or-later
  11. */
  12. #include "defs.h"
  13. #include "print_fields.h"
  14. #include "msghdr.h"
  15. #include <limits.h>
  16. #include <arpa/inet.h>
  17. #include <netinet/in.h>
  18. #define XLAT_MACROS_ONLY
  19. #include "xlat/sock_options.h"
  20. #undef XLAT_MACROS_ONLY
  21. #include "xlat/msg_flags.h"
  22. #include "xlat/scmvals.h"
  23. #include "xlat/ip_cmsg_types.h"
  24. #ifndef current_wordsize
  25. struct cmsghdr32 {
  26. uint32_t cmsg_len;
  27. int cmsg_level;
  28. int cmsg_type;
  29. };
  30. #endif
  31. typedef union {
  32. char *ptr;
  33. struct cmsghdr *cmsg;
  34. #ifndef current_wordsize
  35. struct cmsghdr32 *cmsg32;
  36. #endif
  37. } union_cmsghdr;
  38. static void
  39. print_scm_rights(struct tcb *tcp, const void *cmsg_data,
  40. const unsigned int data_len)
  41. {
  42. const int *fds = cmsg_data;
  43. const unsigned int nfds = data_len / sizeof(*fds);
  44. unsigned int i;
  45. tprints("[");
  46. for (i = 0; i < nfds; ++i) {
  47. if (i)
  48. tprints(", ");
  49. if (abbrev(tcp) && i >= max_strlen) {
  50. tprints("...");
  51. break;
  52. }
  53. printfd(tcp, fds[i]);
  54. }
  55. tprints("]");
  56. }
  57. static void
  58. print_scm_creds(struct tcb *tcp, const void *cmsg_data,
  59. const unsigned int data_len)
  60. {
  61. const struct ucred *uc = cmsg_data;
  62. PRINT_FIELD_U("{", *uc, pid);
  63. PRINT_FIELD_UID(", ", *uc, uid);
  64. PRINT_FIELD_UID(", ", *uc, gid);
  65. tprints("}");
  66. }
  67. static void
  68. print_scm_security(struct tcb *tcp, const void *cmsg_data,
  69. const unsigned int data_len)
  70. {
  71. print_quoted_string(cmsg_data, data_len, 0);
  72. }
  73. static void
  74. print_scm_timestamp_old(struct tcb *tcp, const void *cmsg_data,
  75. const unsigned int data_len)
  76. {
  77. print_struct_timeval_data_size(cmsg_data, data_len);
  78. }
  79. static void
  80. print_scm_timestampns_old(struct tcb *tcp, const void *cmsg_data,
  81. const unsigned int data_len)
  82. {
  83. print_struct_timespec_data_size(cmsg_data, data_len);
  84. }
  85. static void
  86. print_scm_timestamping_old(struct tcb *tcp, const void *cmsg_data,
  87. const unsigned int data_len)
  88. {
  89. print_struct_timespec_array_data_size(cmsg_data, 3, data_len);
  90. }
  91. static void
  92. print_scm_timestamp_new(struct tcb *tcp, const void *cmsg_data,
  93. const unsigned int data_len)
  94. {
  95. print_timeval64_data_size(cmsg_data, data_len);
  96. }
  97. static void
  98. print_scm_timestampns_new(struct tcb *tcp, const void *cmsg_data,
  99. const unsigned int data_len)
  100. {
  101. print_timespec64_data_size(cmsg_data, data_len);
  102. }
  103. static void
  104. print_scm_timestamping_new(struct tcb *tcp, const void *cmsg_data,
  105. const unsigned int data_len)
  106. {
  107. print_timespec64_array_data_size(cmsg_data, 3, data_len);
  108. }
  109. static void
  110. print_cmsg_ip_pktinfo(struct tcb *tcp, const void *cmsg_data,
  111. const unsigned int data_len)
  112. {
  113. const struct in_pktinfo *info = cmsg_data;
  114. PRINT_FIELD_IFINDEX("{", *info, ipi_ifindex);
  115. PRINT_FIELD_INET_ADDR(", ", *info, ipi_spec_dst, AF_INET);
  116. PRINT_FIELD_INET_ADDR(", ", *info, ipi_addr, AF_INET);
  117. tprints("}");
  118. }
  119. static void
  120. print_cmsg_uint(struct tcb *tcp, const void *cmsg_data,
  121. const unsigned int data_len)
  122. {
  123. const unsigned int *p = cmsg_data;
  124. tprintf("[%u]", *p);
  125. }
  126. static void
  127. print_cmsg_uint8_t(struct tcb *tcp, const void *cmsg_data,
  128. const unsigned int data_len)
  129. {
  130. const uint8_t *p = cmsg_data;
  131. tprintf("[%#x]", *p);
  132. }
  133. static void
  134. print_cmsg_ip_opts(struct tcb *tcp, const void *cmsg_data,
  135. const unsigned int data_len)
  136. {
  137. const unsigned char *opts = cmsg_data;
  138. unsigned int i;
  139. tprints("[");
  140. for (i = 0; i < data_len; ++i) {
  141. if (i)
  142. tprints(", ");
  143. if (abbrev(tcp) && i >= max_strlen) {
  144. tprints("...");
  145. break;
  146. }
  147. tprintf("0x%02x", opts[i]);
  148. }
  149. tprints("]");
  150. }
  151. struct sock_ee {
  152. uint32_t ee_errno;
  153. uint8_t ee_origin;
  154. uint8_t ee_type;
  155. uint8_t ee_code;
  156. uint8_t ee_pad;
  157. uint32_t ee_info;
  158. uint32_t ee_data;
  159. struct sockaddr_in offender;
  160. };
  161. static void
  162. print_cmsg_ip_recverr(struct tcb *tcp, const void *cmsg_data,
  163. const unsigned int data_len)
  164. {
  165. const struct sock_ee *const err = cmsg_data;
  166. PRINT_FIELD_U("{", *err, ee_errno);
  167. PRINT_FIELD_U(", ", *err, ee_origin);
  168. PRINT_FIELD_U(", ", *err, ee_type);
  169. PRINT_FIELD_U(", ", *err, ee_code);
  170. PRINT_FIELD_U(", ", *err, ee_info);
  171. PRINT_FIELD_U(", ", *err, ee_data);
  172. PRINT_FIELD_SOCKADDR(", ", *err, offender);
  173. tprints("}");
  174. }
  175. static void
  176. print_cmsg_ip_origdstaddr(struct tcb *tcp, const void *cmsg_data,
  177. const unsigned int data_len)
  178. {
  179. const unsigned int addr_len =
  180. data_len > sizeof(struct sockaddr_storage)
  181. ? sizeof(struct sockaddr_storage) : data_len;
  182. print_sockaddr(cmsg_data, addr_len);
  183. }
  184. typedef void (* const cmsg_printer)(struct tcb *, const void *, unsigned int);
  185. static const struct {
  186. const cmsg_printer printer;
  187. const unsigned int min_len;
  188. } cmsg_socket_printers[] = {
  189. [SCM_RIGHTS] = { print_scm_rights, sizeof(int) },
  190. [SCM_CREDENTIALS] = { print_scm_creds, sizeof(struct ucred) },
  191. [SCM_SECURITY] = { print_scm_security, 1 },
  192. [SO_TIMESTAMP_OLD] = { print_scm_timestamp_old, 1 },
  193. [SO_TIMESTAMPNS_OLD] = { print_scm_timestampns_old, 1 },
  194. [SO_TIMESTAMPING_OLD] = { print_scm_timestamping_old, 1 },
  195. [SO_TIMESTAMP_NEW] = { print_scm_timestamp_new, 1 },
  196. [SO_TIMESTAMPNS_NEW] = { print_scm_timestampns_new, 1 },
  197. [SO_TIMESTAMPING_NEW] = { print_scm_timestamping_new, 1 }
  198. }, cmsg_ip_printers[] = {
  199. [IP_PKTINFO] = { print_cmsg_ip_pktinfo, sizeof(struct in_pktinfo) },
  200. [IP_TTL] = { print_cmsg_uint, sizeof(unsigned int) },
  201. [IP_TOS] = { print_cmsg_uint8_t, 1 },
  202. [IP_RECVOPTS] = { print_cmsg_ip_opts, 1 },
  203. [IP_RETOPTS] = { print_cmsg_ip_opts, 1 },
  204. [IP_RECVERR] = { print_cmsg_ip_recverr, sizeof(struct sock_ee) },
  205. [IP_ORIGDSTADDR] = { print_cmsg_ip_origdstaddr, sizeof(struct sockaddr_in) },
  206. [IP_CHECKSUM] = { print_cmsg_uint, sizeof(unsigned int) },
  207. [SCM_SECURITY] = { print_scm_security, 1 }
  208. };
  209. static void
  210. print_cmsg_type_data(struct tcb *tcp, const int cmsg_level, const int cmsg_type,
  211. const void *cmsg_data, const unsigned int data_len)
  212. {
  213. const unsigned int utype = cmsg_type;
  214. switch (cmsg_level) {
  215. case SOL_SOCKET:
  216. printxval(scmvals, cmsg_type, "SCM_???");
  217. if (utype < ARRAY_SIZE(cmsg_socket_printers)
  218. && cmsg_socket_printers[utype].printer
  219. && data_len >= cmsg_socket_printers[utype].min_len) {
  220. tprints(", cmsg_data=");
  221. cmsg_socket_printers[utype].printer(tcp, cmsg_data, data_len);
  222. }
  223. break;
  224. case SOL_IP:
  225. printxval(ip_cmsg_types, cmsg_type, "IP_???");
  226. if (utype < ARRAY_SIZE(cmsg_ip_printers)
  227. && cmsg_ip_printers[utype].printer
  228. && data_len >= cmsg_ip_printers[utype].min_len) {
  229. tprints(", cmsg_data=");
  230. cmsg_ip_printers[utype].printer(tcp, cmsg_data, data_len);
  231. }
  232. break;
  233. default:
  234. tprintf("%#x", cmsg_type);
  235. }
  236. }
  237. static unsigned int
  238. get_optmem_max(struct tcb *tcp)
  239. {
  240. static int optmem_max;
  241. if (!optmem_max) {
  242. if (read_int_from_file(tcp, "/proc/sys/net/core/optmem_max",
  243. &optmem_max) || optmem_max <= 0) {
  244. optmem_max = sizeof(long long) * (2 * IOV_MAX + 512);
  245. } else {
  246. optmem_max = (optmem_max + sizeof(long long) - 1)
  247. & ~(sizeof(long long) - 1);
  248. }
  249. }
  250. return optmem_max;
  251. }
  252. static void
  253. decode_msg_control(struct tcb *const tcp, const kernel_ulong_t addr,
  254. const kernel_ulong_t in_control_len)
  255. {
  256. if (!in_control_len)
  257. return;
  258. tprints(", msg_control=");
  259. const unsigned int cmsg_size =
  260. #ifndef current_wordsize
  261. (current_wordsize < sizeof(long)) ? sizeof(struct cmsghdr32) :
  262. #endif
  263. sizeof(struct cmsghdr);
  264. unsigned int control_len = in_control_len > get_optmem_max(tcp)
  265. ? get_optmem_max(tcp) : in_control_len;
  266. unsigned int buf_len = control_len;
  267. char *buf = buf_len < cmsg_size ? NULL : malloc(buf_len);
  268. if (!buf || umoven(tcp, addr, buf_len, buf) < 0) {
  269. printaddr(addr);
  270. free(buf);
  271. return;
  272. }
  273. union_cmsghdr u = { .ptr = buf };
  274. tprints("[");
  275. while (buf_len >= cmsg_size) {
  276. const kernel_ulong_t cmsg_len =
  277. #ifndef current_wordsize
  278. (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_len :
  279. #endif
  280. u.cmsg->cmsg_len;
  281. const int cmsg_level =
  282. #ifndef current_wordsize
  283. (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_level :
  284. #endif
  285. u.cmsg->cmsg_level;
  286. const int cmsg_type =
  287. #ifndef current_wordsize
  288. (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_type :
  289. #endif
  290. u.cmsg->cmsg_type;
  291. if (u.ptr != buf)
  292. tprints(", ");
  293. tprintf("{cmsg_len=%" PRI_klu ", cmsg_level=", cmsg_len);
  294. printxval(socketlayers, cmsg_level, "SOL_???");
  295. tprints(", cmsg_type=");
  296. kernel_ulong_t len = cmsg_len > buf_len ? buf_len : cmsg_len;
  297. print_cmsg_type_data(tcp, cmsg_level, cmsg_type,
  298. (const void *) (u.ptr + cmsg_size),
  299. len > cmsg_size ? len - cmsg_size : 0);
  300. tprints("}");
  301. if (len < cmsg_size) {
  302. buf_len -= cmsg_size;
  303. break;
  304. }
  305. len = (cmsg_len + current_wordsize - 1) &
  306. ~((kernel_ulong_t) current_wordsize - 1);
  307. if (len >= buf_len) {
  308. buf_len = 0;
  309. break;
  310. }
  311. u.ptr += len;
  312. buf_len -= len;
  313. }
  314. if (buf_len) {
  315. tprints(", ...");
  316. printaddr_comment(addr + (control_len - buf_len));
  317. } else if (control_len < in_control_len) {
  318. tprints(", ...");
  319. }
  320. tprints("]");
  321. free(buf);
  322. }
  323. void
  324. print_struct_msghdr(struct tcb *tcp, const struct msghdr *msg,
  325. const int *const p_user_msg_namelen,
  326. const kernel_ulong_t data_size)
  327. {
  328. const int msg_namelen =
  329. p_user_msg_namelen && (int) msg->msg_namelen > *p_user_msg_namelen
  330. ? *p_user_msg_namelen : (int) msg->msg_namelen;
  331. tprints("{msg_name=");
  332. const int family =
  333. decode_sockaddr(tcp, ptr_to_kulong(msg->msg_name), msg_namelen);
  334. const enum iov_decode decode =
  335. (family == AF_NETLINK) ? IOV_DECODE_NETLINK : IOV_DECODE_STR;
  336. tprints(", msg_namelen=");
  337. if (p_user_msg_namelen && *p_user_msg_namelen != (int) msg->msg_namelen)
  338. tprintf("%d->", *p_user_msg_namelen);
  339. tprintf("%d", msg->msg_namelen);
  340. tprints(", msg_iov=");
  341. tprint_iov_upto(tcp, msg->msg_iovlen,
  342. ptr_to_kulong(msg->msg_iov), decode, data_size);
  343. PRINT_FIELD_U(", ", *msg, msg_iovlen);
  344. decode_msg_control(tcp, ptr_to_kulong(msg->msg_control),
  345. msg->msg_controllen);
  346. PRINT_FIELD_U(", ", *msg, msg_controllen);
  347. PRINT_FIELD_FLAGS(", ", *msg, msg_flags, msg_flags, "MSG_???");
  348. tprints("}");
  349. }
  350. static bool
  351. fetch_msghdr_namelen(struct tcb *const tcp, const kernel_ulong_t addr,
  352. int *const p_msg_namelen)
  353. {
  354. struct msghdr msg;
  355. if (addr && verbose(tcp) && fetch_struct_msghdr(tcp, addr, &msg)) {
  356. *p_msg_namelen = msg.msg_namelen;
  357. return true;
  358. } else {
  359. return false;
  360. }
  361. }
  362. static void
  363. decode_msghdr(struct tcb *const tcp, const int *const p_user_msg_namelen,
  364. const kernel_ulong_t addr, const kernel_ulong_t data_size)
  365. {
  366. struct msghdr msg;
  367. if (addr && verbose(tcp) && fetch_struct_msghdr(tcp, addr, &msg))
  368. print_struct_msghdr(tcp, &msg, p_user_msg_namelen, data_size);
  369. else
  370. printaddr(addr);
  371. }
  372. void
  373. dumpiov_in_msghdr(struct tcb *const tcp, const kernel_ulong_t addr,
  374. const kernel_ulong_t data_size)
  375. {
  376. struct msghdr msg;
  377. if (fetch_struct_msghdr(tcp, addr, &msg)) {
  378. dumpiov_upto(tcp, msg.msg_iovlen,
  379. ptr_to_kulong(msg.msg_iov), data_size);
  380. }
  381. }
  382. SYS_FUNC(sendmsg)
  383. {
  384. printfd(tcp, tcp->u_arg[0]);
  385. tprints(", ");
  386. decode_msghdr(tcp, 0, tcp->u_arg[1], -1);
  387. /* flags */
  388. tprints(", ");
  389. printflags(msg_flags, tcp->u_arg[2], "MSG_???");
  390. return RVAL_DECODED;
  391. }
  392. SYS_FUNC(recvmsg)
  393. {
  394. int msg_namelen;
  395. if (entering(tcp)) {
  396. printfd(tcp, tcp->u_arg[0]);
  397. tprints(", ");
  398. if (fetch_msghdr_namelen(tcp, tcp->u_arg[1], &msg_namelen)) {
  399. set_tcb_priv_ulong(tcp, msg_namelen);
  400. return 0;
  401. }
  402. printaddr(tcp->u_arg[1]);
  403. } else {
  404. msg_namelen = get_tcb_priv_ulong(tcp);
  405. if (syserror(tcp))
  406. tprintf("{msg_namelen=%d}", msg_namelen);
  407. else
  408. decode_msghdr(tcp, &msg_namelen, tcp->u_arg[1],
  409. tcp->u_rval);
  410. }
  411. /* flags */
  412. tprints(", ");
  413. printflags(msg_flags, tcp->u_arg[2], "MSG_???");
  414. return RVAL_DECODED;
  415. }