(root)/
strace-6.5/
src/
ipc_msgctl.c
       1  /*
       2   * Copyright (c) 1993 Ulrich Pegelow <pegelow@moorea.uni-muenster.de>
       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) 2003-2006 Roland McGrath <roland@redhat.com>
       7   * Copyright (c) 2006-2015 Dmitry V. Levin <ldv@strace.io>
       8   * Copyright (c) 2015-2021 The strace developers.
       9   * All rights reserved.
      10   *
      11   * SPDX-License-Identifier: LGPL-2.1-or-later
      12   */
      13  
      14  #include "defs.h"
      15  
      16  #include DEF_MPERS_TYPE(msqid_ds_t)
      17  
      18  #include "ipc_defs.h"
      19  
      20  #include MSG_H_PROVIDER
      21  typedef struct NAME_OF_STRUCT_MSQID_DS msqid_ds_t;
      22  
      23  #include MPERS_DEFS
      24  
      25  #include "xlat/msgctl_flags.h"
      26  
      27  #define key NAME_OF_STRUCT_IPC_PERM_KEY
      28  
      29  static void
      30  print_ipc_perm(const typeof_field(msqid_ds_t, msg_perm) *const p,
      31  	       const unsigned int cmd)
      32  {
      33  	tprint_struct_begin();
      34  	PRINT_FIELD_ID(*p, uid);
      35  	tprint_struct_next();
      36  	PRINT_FIELD_ID(*p, gid);
      37  	tprint_struct_next();
      38  	PRINT_FIELD_OBJ_U(*p, mode, print_numeric_ll_umode_t);
      39  	if (cmd != IPC_SET) {
      40  		tprint_struct_next();
      41  		PRINT_FIELD_U(*p, key);
      42  		tprint_struct_next();
      43  		PRINT_FIELD_ID(*p, cuid);
      44  		tprint_struct_next();
      45  		PRINT_FIELD_ID(*p, cgid);
      46  	}
      47  	tprint_struct_end();
      48  }
      49  
      50  static void
      51  print_msqid_ds(struct tcb *const tcp, const kernel_ulong_t addr,
      52  	       const unsigned int cmd)
      53  {
      54  	msqid_ds_t msqid_ds;
      55  
      56  	if (umove_or_printaddr(tcp, addr, &msqid_ds))
      57  		return;
      58  
      59  	tprint_struct_begin();
      60  	PRINT_FIELD_OBJ_PTR(msqid_ds, msg_perm, print_ipc_perm, cmd);
      61  	if (cmd != IPC_SET) {
      62  		tprint_struct_next();
      63  		PRINT_FIELD_U(msqid_ds, msg_stime);
      64  		tprint_struct_next();
      65  		PRINT_FIELD_U(msqid_ds, msg_rtime);
      66  		tprint_struct_next();
      67  		PRINT_FIELD_U(msqid_ds, msg_ctime);
      68  		tprint_struct_next();
      69  		PRINT_FIELD_U(msqid_ds, msg_qnum);
      70  	}
      71  	tprint_struct_next();
      72  	PRINT_FIELD_U(msqid_ds, msg_qbytes);
      73  	if (cmd != IPC_SET) {
      74  		tprint_struct_next();
      75  		PRINT_FIELD_D(msqid_ds, msg_lspid);
      76  		tprint_struct_next();
      77  		PRINT_FIELD_D(msqid_ds, msg_lrpid);
      78  	}
      79  	tprint_struct_end();
      80  }
      81  
      82  static void
      83  print_msginfo(struct tcb *const tcp, const kernel_ulong_t addr,
      84  	      const unsigned int cmd)
      85  {
      86  	struct msginfo info;
      87  
      88  	if (umove_or_printaddr(tcp, addr, &info))
      89  		return;
      90  
      91  	tprint_struct_begin();
      92  	PRINT_FIELD_D(info, msgpool);
      93  	tprint_struct_next();
      94  	PRINT_FIELD_D(info, msgmap);
      95  	tprint_struct_next();
      96  	PRINT_FIELD_D(info, msgmax);
      97  	tprint_struct_next();
      98  	PRINT_FIELD_D(info, msgmnb);
      99  	tprint_struct_next();
     100  	PRINT_FIELD_D(info, msgmni);
     101  	tprint_struct_next();
     102  	PRINT_FIELD_D(info, msgssz);
     103  	tprint_struct_next();
     104  	PRINT_FIELD_D(info, msgtql);
     105  	tprint_struct_next();
     106  	PRINT_FIELD_U(info, msgseg);
     107  	tprint_struct_end();
     108  }
     109  
     110  SYS_FUNC(msgctl)
     111  {
     112  	const kernel_ulong_t addr = tcp->u_arg[indirect_ipccall(tcp) ? 3 : 2];
     113  	unsigned int cmd = tcp->u_arg[1];
     114  
     115  	/* TODO: We don't properly decode old compat ipc calls. */
     116  	if (cmd & IPC_64)
     117  		cmd &= ~IPC_64;
     118  
     119  	if (entering(tcp)) {
     120  		/* msqid */
     121  		PRINT_VAL_D((int) tcp->u_arg[0]);
     122  		tprint_arg_next();
     123  
     124  		/* cmd */
     125  		PRINTCTL(msgctl_flags, tcp->u_arg[1], "MSG_???");
     126  		tprint_arg_next();
     127  
     128  		switch (cmd) {
     129  		case IPC_SET:
     130  			/* buf */
     131  			print_msqid_ds(tcp, addr, cmd);
     132  			return RVAL_DECODED;
     133  
     134  		case IPC_STAT:
     135  		case MSG_STAT:
     136  		case MSG_STAT_ANY:
     137  		case IPC_INFO:
     138  		case MSG_INFO:
     139  			/* decode on exiting */
     140  			break;
     141  
     142  		default:
     143  			/* buf */
     144  			printaddr(addr);
     145  			return RVAL_DECODED;
     146  		}
     147  	} else {
     148  		switch (cmd) {
     149  		case IPC_STAT:
     150  		case MSG_STAT:
     151  		case MSG_STAT_ANY:
     152  			/* buf */
     153  			print_msqid_ds(tcp, addr, cmd);
     154  			break;
     155  
     156  		case IPC_INFO:
     157  		case MSG_INFO:
     158  			/* buf */
     159  			print_msginfo(tcp, addr, cmd);
     160  			break;
     161  		}
     162  	}
     163  	return 0;
     164  }