(root)/
strace-6.5/
src/
ipc_shmctl.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(shmid_ds_t)
      17  #include DEF_MPERS_TYPE(struct_shm_info_t)
      18  #include DEF_MPERS_TYPE(struct_shm_ipc_info_t)
      19  
      20  #include "ipc_defs.h"
      21  
      22  #include SHM_H_PROVIDER
      23  typedef struct NAME_OF_STRUCT_SHMID_DS shmid_ds_t;
      24  typedef struct shm_info struct_shm_info_t;
      25  typedef struct NAME_OF_STRUCT_SHMINFO struct_shm_ipc_info_t;
      26  
      27  #include MPERS_DEFS
      28  
      29  #include "xlat/shmctl_flags.h"
      30  
      31  #define key NAME_OF_STRUCT_IPC_PERM_KEY
      32  
      33  static void
      34  print_ipc_perm(const typeof_field(shmid_ds_t, shm_perm) *const p,
      35  	       const unsigned int cmd)
      36  {
      37  	tprint_struct_begin();
      38  	PRINT_FIELD_ID(*p, uid);
      39  	tprint_struct_next();
      40  	PRINT_FIELD_ID(*p, gid);
      41  	tprint_struct_next();
      42  	PRINT_FIELD_OBJ_U(*p, mode, print_numeric_ll_umode_t);
      43  	if (cmd != IPC_SET) {
      44  		tprint_struct_next();
      45  		PRINT_FIELD_U(*p, key);
      46  		tprint_struct_next();
      47  		PRINT_FIELD_ID(*p, cuid);
      48  		tprint_struct_next();
      49  		PRINT_FIELD_ID(*p, cgid);
      50  	}
      51  	tprint_struct_end();
      52  }
      53  
      54  static void
      55  print_shmid_ds(struct tcb *const tcp, const kernel_ulong_t addr,
      56  	       const unsigned int cmd)
      57  {
      58  	shmid_ds_t shmid_ds;
      59  
      60  	if (umove_or_printaddr(tcp, addr, &shmid_ds))
      61  		return;
      62  
      63  	tprint_struct_begin();
      64  	PRINT_FIELD_OBJ_PTR(shmid_ds, shm_perm, print_ipc_perm, cmd);
      65  	if (cmd != IPC_SET) {
      66  		tprint_struct_next();
      67  		PRINT_FIELD_U(shmid_ds, shm_segsz);
      68  		tprint_struct_next();
      69  		PRINT_FIELD_TGID(shmid_ds, shm_cpid, tcp);
      70  		tprint_struct_next();
      71  		PRINT_FIELD_TGID(shmid_ds, shm_lpid, tcp);
      72  		tprint_struct_next();
      73  		PRINT_FIELD_U(shmid_ds, shm_nattch);
      74  		tprint_struct_next();
      75  		PRINT_FIELD_U(shmid_ds, shm_atime);
      76  		tprint_struct_next();
      77  		PRINT_FIELD_U(shmid_ds, shm_dtime);
      78  		tprint_struct_next();
      79  		PRINT_FIELD_U(shmid_ds, shm_ctime);
      80  	}
      81  	tprint_struct_end();
      82  }
      83  
      84  static void
      85  print_ipc_info(struct tcb *const tcp, const kernel_ulong_t addr,
      86  	       const unsigned int cmd)
      87  {
      88  	struct_shm_ipc_info_t info;
      89  
      90  	if (umove_or_printaddr(tcp, addr, &info))
      91  		return;
      92  
      93  	tprint_struct_begin();
      94  	PRINT_FIELD_U(info, shmmax);
      95  	tprint_struct_next();
      96  	PRINT_FIELD_U(info, shmmin);
      97  	tprint_struct_next();
      98  	PRINT_FIELD_U(info, shmmni);
      99  	tprint_struct_next();
     100  	PRINT_FIELD_U(info, shmseg);
     101  	tprint_struct_next();
     102  	PRINT_FIELD_U(info, shmall);
     103  	tprint_struct_end();
     104  }
     105  
     106  static void
     107  print_shm_info(struct tcb *const tcp, const kernel_ulong_t addr,
     108  	       const unsigned int cmd)
     109  {
     110  	struct_shm_info_t info;
     111  
     112  	if (umove_or_printaddr(tcp, addr, &info))
     113  		return;
     114  
     115  	tprint_struct_begin();
     116  	PRINT_FIELD_D(info, used_ids);
     117  	tprint_struct_next();
     118  	PRINT_FIELD_U(info, shm_tot);
     119  	tprint_struct_next();
     120  	PRINT_FIELD_U(info, shm_rss);
     121  	tprint_struct_next();
     122  	PRINT_FIELD_U(info, shm_swp);
     123  	tprint_struct_next();
     124  	PRINT_FIELD_U(info, swap_attempts);
     125  	tprint_struct_next();
     126  	PRINT_FIELD_U(info, swap_successes);
     127  	tprint_struct_end();
     128  }
     129  
     130  SYS_FUNC(shmctl)
     131  {
     132  	const kernel_ulong_t addr = tcp->u_arg[indirect_ipccall(tcp) ? 3 : 2];
     133  	unsigned int cmd = tcp->u_arg[1];
     134  
     135  	/* TODO: We don't properly decode old compat ipc calls. */
     136  	if (cmd & IPC_64)
     137  		cmd &= ~IPC_64;
     138  
     139  	if (entering(tcp)) {
     140  		/* shmid */
     141  		PRINT_VAL_D((int) tcp->u_arg[0]);
     142  		tprint_arg_next();
     143  
     144  		/* cmd */
     145  		PRINTCTL(shmctl_flags, tcp->u_arg[1], "SHM_???");
     146  		tprint_arg_next();
     147  
     148  		switch (cmd) {
     149  		case IPC_SET:
     150  			/* buf */
     151  			print_shmid_ds(tcp, addr, cmd);
     152  			return RVAL_DECODED;
     153  
     154  		case IPC_STAT:
     155  		case SHM_STAT:
     156  		case SHM_STAT_ANY:
     157  		case IPC_INFO:
     158  		case SHM_INFO:
     159  			/* decode on exiting */
     160  			break;
     161  
     162  		default:
     163  			/* buf */
     164  			printaddr(addr);
     165  			return RVAL_DECODED;
     166  		}
     167  	} else {
     168  		switch (cmd) {
     169  		case IPC_STAT:
     170  		case SHM_STAT:
     171  		case SHM_STAT_ANY:
     172  			/* buf */
     173  			print_shmid_ds(tcp, addr, cmd);
     174  			break;
     175  
     176  		case IPC_INFO:
     177  			/* buf */
     178  			print_ipc_info(tcp, addr, cmd);
     179  			break;
     180  
     181  		case SHM_INFO:
     182  			/* buf */
     183  			print_shm_info(tcp, addr, cmd);
     184  			break;
     185  		}
     186  	}
     187  	return 0;
     188  }