(root)/
strace-6.5/
src/
msghdr.c
       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@strace.io>
       7   * Copyright (c) 2016-2023 The strace developers.
       8   * All rights reserved.
       9   *
      10   * SPDX-License-Identifier: LGPL-2.1-or-later
      11   */
      12  
      13  #include "defs.h"
      14  #include "msghdr.h"
      15  #include <limits.h>
      16  #include <arpa/inet.h>
      17  #include <netinet/in.h>
      18  
      19  #define XLAT_MACROS_ONLY
      20  #include "xlat/sock_options.h"
      21  #undef XLAT_MACROS_ONLY
      22  #include "xlat/msg_flags.h"
      23  #include "xlat/scmvals.h"
      24  #include "xlat/ip_cmsg_types.h"
      25  
      26  #ifndef current_wordsize
      27  struct cmsghdr32 {
      28  	uint32_t cmsg_len;
      29  	int cmsg_level;
      30  	int cmsg_type;
      31  };
      32  #endif
      33  
      34  typedef union {
      35  	char *ptr;
      36  	struct cmsghdr *cmsg;
      37  #ifndef current_wordsize
      38  	struct cmsghdr32 *cmsg32;
      39  #endif
      40  } union_cmsghdr;
      41  
      42  static void
      43  print_scm_rights(struct tcb *tcp, const void *cmsg_data,
      44  		 const unsigned int data_len)
      45  {
      46  	const int *fds = cmsg_data;
      47  	const unsigned int nfds = data_len / sizeof(*fds);
      48  
      49  	print_local_array_ex(tcp, fds, nfds, sizeof(*fds),
      50  			     print_fd_array_member, NULL, 0, NULL, NULL);
      51  
      52  }
      53  
      54  static void
      55  print_scm_creds(struct tcb *tcp, const void *cmsg_data,
      56  		const unsigned int data_len)
      57  {
      58  	const struct ucred *uc = cmsg_data;
      59  
      60  	tprint_struct_begin();
      61  	PRINT_FIELD_TGID(*uc, pid, tcp);
      62  	tprint_struct_next();
      63  	PRINT_FIELD_ID(*uc, uid);
      64  	tprint_struct_next();
      65  	PRINT_FIELD_ID(*uc, gid);
      66  	tprint_struct_end();
      67  }
      68  
      69  static void
      70  print_scm_security(struct tcb *tcp, const void *cmsg_data,
      71  		   const unsigned int data_len)
      72  {
      73  	print_quoted_string(cmsg_data, data_len, 0);
      74  }
      75  
      76  static void
      77  print_scm_pidfd(struct tcb *tcp, const void *cmsg_data,
      78  		const unsigned int data_len)
      79  {
      80  	const int *fd = cmsg_data;
      81  
      82  	printfd(tcp, *fd);
      83  }
      84  
      85  static void
      86  print_scm_timestamp_old(struct tcb *tcp, const void *cmsg_data,
      87  			const unsigned int data_len)
      88  {
      89  	print_struct_timeval_data_size(cmsg_data, data_len);
      90  }
      91  
      92  #ifdef current_klongsize
      93  # if current_klongsize == 4
      94  #  define PRINT_TIMESPEC_DATA_SIZE print_timespec32_data_size
      95  #  define PRINT_TIMESPEC_ARRAY_DATA_SIZE print_timespec32_array_data_size
      96  # else
      97  #  define PRINT_TIMESPEC_DATA_SIZE print_timespec64_data_size
      98  #  define PRINT_TIMESPEC_ARRAY_DATA_SIZE print_timespec64_array_data_size
      99  # endif
     100  #else
     101  # define PRINT_TIMESPEC_DATA_SIZE			\
     102  	((current_klongsize == 4) ?			\
     103  		print_timespec32_data_size :		\
     104  		print_timespec64_data_size)
     105  # define PRINT_TIMESPEC_ARRAY_DATA_SIZE			\
     106  	((current_klongsize == 4) ?			\
     107  		print_timespec32_array_data_size :	\
     108  		print_timespec64_array_data_size)
     109  #endif
     110  
     111  static void
     112  print_scm_timestampns_old(struct tcb *tcp, const void *cmsg_data,
     113  			  const unsigned int data_len)
     114  {
     115  	PRINT_TIMESPEC_DATA_SIZE(cmsg_data, data_len);
     116  }
     117  
     118  static void
     119  print_scm_timestamping_old(struct tcb *tcp, const void *cmsg_data,
     120  			   const unsigned int data_len)
     121  {
     122  	PRINT_TIMESPEC_ARRAY_DATA_SIZE(cmsg_data, 3, data_len);
     123  }
     124  
     125  static void
     126  print_scm_timestamp_new(struct tcb *tcp, const void *cmsg_data,
     127  			const unsigned int data_len)
     128  {
     129  	print_timeval64_data_size(cmsg_data, data_len);
     130  }
     131  
     132  static void
     133  print_scm_timestampns_new(struct tcb *tcp, const void *cmsg_data,
     134  			const unsigned int data_len)
     135  {
     136  	print_timespec64_data_size(cmsg_data, data_len);
     137  }
     138  
     139  static void
     140  print_scm_timestamping_new(struct tcb *tcp, const void *cmsg_data,
     141  			   const unsigned int data_len)
     142  {
     143  	print_timespec64_array_data_size(cmsg_data, 3, data_len);
     144  }
     145  
     146  static void
     147  print_cmsg_ip_pktinfo(struct tcb *tcp, const void *cmsg_data,
     148  		      const unsigned int data_len)
     149  {
     150  	const struct in_pktinfo *info = cmsg_data;
     151  
     152  	tprint_struct_begin();
     153  	PRINT_FIELD_IFINDEX(*info, ipi_ifindex);
     154  	tprint_struct_next();
     155  	PRINT_FIELD_INET_ADDR(*info, ipi_spec_dst, AF_INET);
     156  	tprint_struct_next();
     157  	PRINT_FIELD_INET_ADDR(*info, ipi_addr, AF_INET);
     158  	tprint_struct_end();
     159  }
     160  
     161  static void
     162  print_cmsg_uint(struct tcb *tcp, const void *cmsg_data,
     163  		const unsigned int data_len)
     164  {
     165  	const unsigned int *p = cmsg_data;
     166  
     167  	print_local_array_ex(tcp, p, data_len / sizeof(*p), sizeof(*p),
     168  			     print_uint_array_member, NULL, 0, NULL, NULL);
     169  }
     170  
     171  static void
     172  print_cmsg_xint8_t(struct tcb *tcp, const void *cmsg_data,
     173  		   const unsigned int data_len)
     174  {
     175  	print_local_array_ex(tcp, cmsg_data, data_len, 1,
     176  			     print_xint_array_member, NULL, 0, NULL, NULL);
     177  }
     178  
     179  struct sock_ee {
     180  	uint32_t ee_errno;
     181  	uint8_t  ee_origin;
     182  	uint8_t  ee_type;
     183  	uint8_t  ee_code;
     184  	uint8_t  ee_pad;
     185  	uint32_t ee_info;
     186  	uint32_t ee_data;
     187  	struct sockaddr_in offender;
     188  };
     189  
     190  static void
     191  print_cmsg_ip_recverr(struct tcb *tcp, const void *cmsg_data,
     192  		      const unsigned int data_len)
     193  {
     194  	const struct sock_ee *const err = cmsg_data;
     195  
     196  	tprint_struct_begin();
     197  	PRINT_FIELD_U(*err, ee_errno);
     198  	tprint_struct_next();
     199  	PRINT_FIELD_U(*err, ee_origin);
     200  	tprint_struct_next();
     201  	PRINT_FIELD_U(*err, ee_type);
     202  	tprint_struct_next();
     203  	PRINT_FIELD_U(*err, ee_code);
     204  	tprint_struct_next();
     205  	PRINT_FIELD_U(*err, ee_info);
     206  	tprint_struct_next();
     207  	PRINT_FIELD_U(*err, ee_data);
     208  	tprint_struct_next();
     209  	PRINT_FIELD_SOCKADDR(*err, offender, tcp);
     210  	tprint_struct_end();
     211  }
     212  
     213  static void
     214  print_cmsg_ip_origdstaddr(struct tcb *tcp, const void *cmsg_data,
     215  			  const unsigned int data_len)
     216  {
     217  	const unsigned int addr_len =
     218  		data_len > sizeof(struct sockaddr_storage)
     219  		? sizeof(struct sockaddr_storage) : data_len;
     220  
     221  	print_sockaddr(tcp, cmsg_data, addr_len);
     222  }
     223  
     224  static void
     225  print_cmsg_ip_protocol(struct tcb *tcp, const void *cmsg_data,
     226  		       const unsigned int data_len)
     227  {
     228  	const unsigned int *protocol = cmsg_data;
     229  
     230  	tprint_indirect_begin();
     231  	printxval(inet_protocols, *protocol, "IP_???");
     232  	tprint_indirect_end();
     233  }
     234  
     235  typedef void (* const cmsg_printer)(struct tcb *, const void *, unsigned int);
     236  
     237  static const struct {
     238  	const cmsg_printer printer;
     239  	const unsigned int min_len;
     240  } cmsg_socket_printers[] = {
     241  	[SCM_RIGHTS] = { print_scm_rights, sizeof(int) },
     242  	[SCM_CREDENTIALS] = { print_scm_creds, sizeof(struct ucred) },
     243  	[SCM_SECURITY] = { print_scm_security, 1 },
     244  	[SCM_PIDFD] = { print_scm_pidfd, sizeof(int) },
     245  	[SO_TIMESTAMP_OLD] = { print_scm_timestamp_old, 1 },
     246  	[SO_TIMESTAMPNS_OLD] = { print_scm_timestampns_old, 1 },
     247  	[SO_TIMESTAMPING_OLD] = { print_scm_timestamping_old, 1 },
     248  	[SO_TIMESTAMP_NEW] = { print_scm_timestamp_new, 1 },
     249  	[SO_TIMESTAMPNS_NEW] = { print_scm_timestampns_new, 1 },
     250  	[SO_TIMESTAMPING_NEW] = { print_scm_timestamping_new, 1 }
     251  }, cmsg_ip_printers[] = {
     252  	[IP_PKTINFO] = { print_cmsg_ip_pktinfo, sizeof(struct in_pktinfo) },
     253  	[IP_TTL] = { print_cmsg_uint, sizeof(unsigned int) },
     254  	[IP_TOS] = { print_cmsg_xint8_t, 1 },
     255  	[IP_RECVOPTS] = { print_cmsg_xint8_t, 1 },
     256  	[IP_RETOPTS] = { print_cmsg_xint8_t, 1 },
     257  	[IP_RECVERR] = { print_cmsg_ip_recverr, sizeof(struct sock_ee) },
     258  	[IP_ORIGDSTADDR] = { print_cmsg_ip_origdstaddr, sizeof(struct sockaddr_in) },
     259  	[IP_CHECKSUM] = { print_cmsg_uint, sizeof(unsigned int) },
     260  	[IP_PROTOCOL] = { print_cmsg_ip_protocol, sizeof(unsigned int) },
     261  	[SCM_SECURITY] = { print_scm_security, 1 }
     262  };
     263  
     264  static void
     265  print_cmsg_type_data(struct tcb *tcp, const int cmsg_level, const int cmsg_type,
     266  		     const void *cmsg_data, const unsigned int data_len)
     267  {
     268  	const unsigned int utype = cmsg_type;
     269  	switch (cmsg_level) {
     270  	case SOL_SOCKET:
     271  		printxval(scmvals, cmsg_type, "SCM_???");
     272  		if (utype < ARRAY_SIZE(cmsg_socket_printers)
     273  		    && cmsg_socket_printers[utype].printer
     274  		    && data_len >= cmsg_socket_printers[utype].min_len) {
     275  			tprint_struct_next();
     276  			tprints_field_name("cmsg_data");
     277  			cmsg_socket_printers[utype].printer(tcp, cmsg_data, data_len);
     278  		}
     279  		break;
     280  	case SOL_IP:
     281  		printxval(ip_cmsg_types, cmsg_type, "IP_???");
     282  		if (utype < ARRAY_SIZE(cmsg_ip_printers)
     283  		    && cmsg_ip_printers[utype].printer
     284  		    && data_len >= cmsg_ip_printers[utype].min_len) {
     285  			tprint_struct_next();
     286  			tprints_field_name("cmsg_data");
     287  			cmsg_ip_printers[utype].printer(tcp, cmsg_data, data_len);
     288  		}
     289  		break;
     290  	default:
     291  		PRINT_VAL_X(cmsg_type);
     292  	}
     293  }
     294  
     295  static unsigned int
     296  get_optmem_max(struct tcb *tcp)
     297  {
     298  	static int optmem_max;
     299  
     300  	if (!optmem_max) {
     301  		if (read_int_from_file("/proc/sys/net/core/optmem_max",
     302  				       &optmem_max) || optmem_max <= 0) {
     303  			optmem_max = sizeof(long long) * (2 * IOV_MAX + 512);
     304  		} else {
     305  			optmem_max = (optmem_max + sizeof(long long) - 1)
     306  				     & ~(sizeof(long long) - 1);
     307  		}
     308  	}
     309  
     310  	return optmem_max;
     311  }
     312  
     313  static void
     314  decode_msg_control(struct tcb *const tcp, const kernel_ulong_t addr,
     315  		   const kernel_ulong_t in_control_len)
     316  {
     317  	if (!in_control_len)
     318  		return;
     319  	tprint_struct_next();
     320  	tprints_field_name("msg_control");
     321  
     322  	const unsigned int cmsg_size =
     323  #ifndef current_wordsize
     324  		(current_wordsize < sizeof(long)) ? sizeof(struct cmsghdr32) :
     325  #endif
     326  			sizeof(struct cmsghdr);
     327  
     328  	unsigned int control_len = in_control_len > get_optmem_max(tcp)
     329  				   ? get_optmem_max(tcp) : in_control_len;
     330  	unsigned int buf_len = control_len;
     331  	char *buf = buf_len < cmsg_size ? NULL : malloc(buf_len);
     332  	if (!buf || umoven(tcp, addr, buf_len, buf) < 0) {
     333  		printaddr(addr);
     334  		free(buf);
     335  		return;
     336  	}
     337  
     338  	union_cmsghdr u = { .ptr = buf };
     339  
     340  	tprint_array_begin();
     341  	while (buf_len >= cmsg_size) {
     342  		const kernel_ulong_t cmsg_len =
     343  #ifndef current_wordsize
     344  			(current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_len :
     345  #endif
     346  				u.cmsg->cmsg_len;
     347  		const int cmsg_level =
     348  #ifndef current_wordsize
     349  			(current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_level :
     350  #endif
     351  				u.cmsg->cmsg_level;
     352  		const int cmsg_type =
     353  #ifndef current_wordsize
     354  			(current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_type :
     355  #endif
     356  				u.cmsg->cmsg_type;
     357  
     358  		if (u.ptr != buf)
     359  			tprint_array_next();
     360  		tprint_struct_begin();
     361  		tprints_field_name("cmsg_len");
     362  		PRINT_VAL_U(cmsg_len);
     363  		tprint_struct_next();
     364  		tprints_field_name("cmsg_level");
     365  		printxval(socketlayers, cmsg_level, "SOL_???");
     366  		tprint_struct_next();
     367  		tprints_field_name("cmsg_type");
     368  
     369  		kernel_ulong_t len = cmsg_len > buf_len ? buf_len : cmsg_len;
     370  
     371  		print_cmsg_type_data(tcp, cmsg_level, cmsg_type,
     372  				     (const void *) (u.ptr + cmsg_size),
     373  				     len > cmsg_size ? len - cmsg_size : 0);
     374  		tprint_struct_end();
     375  
     376  		if (len < cmsg_size) {
     377  			buf_len -= cmsg_size;
     378  			break;
     379  		}
     380  		len = (cmsg_len + current_wordsize - 1) &
     381  			~((kernel_ulong_t) current_wordsize - 1);
     382  		if (len >= buf_len) {
     383  			buf_len = 0;
     384  			break;
     385  		}
     386  		u.ptr += len;
     387  		buf_len -= len;
     388  	}
     389  	if (buf_len) {
     390  		tprint_array_next();
     391  		tprint_more_data_follows();
     392  		printaddr_comment(addr + (control_len - buf_len));
     393  	} else if (control_len < in_control_len) {
     394  		tprint_array_next();
     395  		tprint_more_data_follows();
     396  	}
     397  	tprint_array_end();
     398  	free(buf);
     399  }
     400  
     401  static void
     402  iov_decode_netlink(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t size,
     403  		   void *opaque_data)
     404  {
     405  	const int *const fdp = opaque_data;
     406  	decode_netlink(tcp, *fdp, addr, size);
     407  }
     408  
     409  void
     410  print_struct_msghdr(struct tcb *tcp, const struct msghdr *msg,
     411  		    const int *const p_user_msg_namelen,
     412  		    const kernel_ulong_t data_size)
     413  {
     414  	const int msg_namelen =
     415  		p_user_msg_namelen && (int) msg->msg_namelen > *p_user_msg_namelen
     416  		? *p_user_msg_namelen : (int) msg->msg_namelen;
     417  
     418  	tprint_struct_begin();
     419  	tprints_field_name("msg_name");
     420  	const int family =
     421  		decode_sockaddr(tcp, ptr_to_kulong(msg->msg_name), msg_namelen);
     422  	/* Assume that the descriptor is the 1st syscall argument. */
     423  	int fd = tcp->u_arg[0];
     424  	const enum sock_proto proto =
     425  		(family == -1) ? getfdproto(tcp, fd) : SOCK_PROTO_UNKNOWN;
     426  	const print_obj_by_addr_size_fn print_func =
     427  		(family == AF_NETLINK || proto == SOCK_PROTO_NETLINK)
     428  		? iov_decode_netlink : iov_decode_str;
     429  
     430  	tprint_struct_next();
     431  	tprints_field_name("msg_namelen");
     432  	if (p_user_msg_namelen && *p_user_msg_namelen != (int) msg->msg_namelen) {
     433  		PRINT_VAL_D(*p_user_msg_namelen);
     434  		tprint_value_changed();
     435  	}
     436  	PRINT_VAL_D(msg->msg_namelen);
     437  
     438  	tprint_struct_next();
     439  	tprints_field_name("msg_iov");
     440  	tprint_iov_upto(tcp, msg->msg_iovlen,
     441  			ptr_to_kulong(msg->msg_iov), data_size, print_func, &fd);
     442  	tprint_struct_next();
     443  	PRINT_FIELD_U(*msg, msg_iovlen);
     444  
     445  	decode_msg_control(tcp, ptr_to_kulong(msg->msg_control),
     446  			   msg->msg_controllen);
     447  	tprint_struct_next();
     448  	PRINT_FIELD_U(*msg, msg_controllen);
     449  
     450  	tprint_struct_next();
     451  	PRINT_FIELD_FLAGS(*msg, msg_flags, msg_flags, "MSG_???");
     452  	tprint_struct_end();
     453  }
     454  
     455  static bool
     456  fetch_msghdr_namelen(struct tcb *const tcp, const kernel_ulong_t addr,
     457  		     int *const p_msg_namelen)
     458  {
     459  	struct msghdr msg;
     460  
     461  	if (addr && verbose(tcp) && fetch_struct_msghdr(tcp, addr, &msg)) {
     462  		*p_msg_namelen = msg.msg_namelen;
     463  		return true;
     464  	} else {
     465  		return false;
     466  	}
     467  }
     468  
     469  static void
     470  decode_msghdr(struct tcb *const tcp, const int *const p_user_msg_namelen,
     471  	      const kernel_ulong_t addr, const kernel_ulong_t data_size)
     472  {
     473  	struct msghdr msg;
     474  
     475  	if (addr && verbose(tcp) && fetch_struct_msghdr(tcp, addr, &msg))
     476  		print_struct_msghdr(tcp, &msg, p_user_msg_namelen, data_size);
     477  	else
     478  		printaddr(addr);
     479  }
     480  
     481  void
     482  dumpiov_in_msghdr(struct tcb *const tcp, const kernel_ulong_t addr,
     483  		  const kernel_ulong_t data_size)
     484  {
     485  	struct msghdr msg;
     486  
     487  	if (fetch_struct_msghdr(tcp, addr, &msg)) {
     488  		dumpiov_upto(tcp, msg.msg_iovlen,
     489  			     ptr_to_kulong(msg.msg_iov), data_size);
     490  	}
     491  }
     492  
     493  SYS_FUNC(sendmsg)
     494  {
     495  	/* sockfd */
     496  	printfd(tcp, tcp->u_arg[0]);
     497  	tprint_arg_next();
     498  
     499  	/* msg */
     500  	decode_msghdr(tcp, 0, tcp->u_arg[1], -1);
     501  	tprint_arg_next();
     502  
     503  	/* flags */
     504  	printflags(msg_flags, tcp->u_arg[2], "MSG_???");
     505  
     506  	return RVAL_DECODED;
     507  }
     508  
     509  SYS_FUNC(recvmsg)
     510  {
     511  	int msg_namelen;
     512  
     513  	if (entering(tcp)) {
     514  		/* sockfd */
     515  		printfd(tcp, tcp->u_arg[0]);
     516  		tprint_arg_next();
     517  
     518  		if (fetch_msghdr_namelen(tcp, tcp->u_arg[1], &msg_namelen)) {
     519  			set_tcb_priv_ulong(tcp, msg_namelen);
     520  			return 0;
     521  		}
     522  		/* msg */
     523  		printaddr(tcp->u_arg[1]);
     524  	} else {
     525  		msg_namelen = get_tcb_priv_ulong(tcp);
     526  
     527  		/* msg */
     528  		if (syserror(tcp)) {
     529  			tprint_struct_begin();
     530  			tprints_field_name("msg_namelen");
     531  			PRINT_VAL_D(msg_namelen);
     532  			tprint_struct_end();
     533  		} else {
     534  			decode_msghdr(tcp, &msg_namelen, tcp->u_arg[1],
     535  				      tcp->u_rval);
     536  		}
     537  	}
     538  	tprint_arg_next();
     539  
     540  	/* flags */
     541  	printflags(msg_flags, tcp->u_arg[2], "MSG_???");
     542  
     543  	return RVAL_DECODED;
     544  }