(root)/
strace-6.5/
src/
seccomp_ioctl.c
       1  /*
       2   * Copyright (c) 2021 Eugene Syromyatnikov <evgsyr@gmail.com>.
       3   * Copyright (c) 2021-2022 The strace developers.
       4   * All rights reserved.
       5   *
       6   * SPDX-License-Identifier: LGPL-2.1-or-later
       7   */
       8  
       9  #include "defs.h"
      10  
      11  #include <linux/ioctl.h>
      12  #include <linux/seccomp.h>
      13  
      14  #include "xlat/seccomp_ioctl_addfd_flags.h"
      15  #include "xlat/seccomp_ioctl_resp_flags.h"
      16  
      17  #define SECCOMP_IOCTL_NOTIF_ID_VALID_WRONG_DIR SECCOMP_IOR(2, __u64)
      18  
      19  static void
      20  print_struct_seccomp_data(struct tcb *const tcp,
      21  			  const struct seccomp_data *const data)
      22  {
      23  	tprint_struct_begin();
      24  	PRINT_FIELD_SYSCALL_NAME(*data, nr, data->arch);
      25  	tprint_struct_next();
      26  	PRINT_FIELD_XVAL(*data, arch, audit_arch, "AUDIT_ARCH_???");
      27  	tprint_struct_next();
      28  	PRINT_FIELD_ADDR64(*data, instruction_pointer);
      29  	tprint_struct_next();
      30  	PRINT_FIELD_ARRAY(*data, args, tcp, print_xint_array_member);
      31  	tprint_struct_end();
      32  }
      33  
      34  static int
      35  print_struct_seccomp_notif(struct tcb *const tcp, const kernel_ulong_t addr)
      36  {
      37  	/*
      38  	 * NB: There is a (poorly designed) seccomp(SECCOMP_GET_NOTIF_SIZES)
      39  	 *     operation that hints that struct seccomp_notif/seccomp_notif_data
      40  	 *     may vary, but that in turn will change the ID of the respective
      41  	 *     ioctl, rendering the whole idea of getting the struct size
      42  	 *     in advance dubious at best.  Let's just put some safeguards
      43  	 *     in place for the time being, in case updated headers bring
      44  	 *     changes in either ioctl code or struct size.
      45  	 */
      46  	CHECK_IOCTL_SIZE(SECCOMP_IOCTL_NOTIF_RECV, 80);
      47  	CHECK_TYPE_SIZE(struct seccomp_notif, 80);
      48  	struct seccomp_notif notif;
      49  
      50  	if (umove_or_printaddr(tcp, addr, &notif))
      51  		return RVAL_IOCTL_DECODED;
      52  
      53  	if (entering(tcp)) {
      54  		if (is_filled((const char *) &notif, 0, sizeof(notif)))
      55  			return 0;
      56  	}
      57  
      58  	tprint_struct_begin();
      59  	PRINT_FIELD_X(notif, id);
      60  	tprint_struct_next();
      61  	PRINT_FIELD_TGID(notif, pid, tcp);
      62  	tprint_struct_next();
      63  	PRINT_FIELD_X(notif, flags);
      64  	tprint_struct_next();
      65  	PRINT_FIELD_OBJ_TCB_PTR(notif, data, tcp, print_struct_seccomp_data);
      66  	tprint_struct_end();
      67  
      68  	if (entering(tcp)) {
      69  		tprint_value_changed();
      70  		return 0;
      71  	}
      72  
      73  	return RVAL_IOCTL_DECODED;
      74  }
      75  
      76  static void
      77  print_struct_seccomp_notif_resp(struct tcb *const tcp,
      78  				const kernel_ulong_t addr)
      79  {
      80  	CHECK_IOCTL_SIZE(SECCOMP_IOCTL_NOTIF_SEND, 24);
      81  	CHECK_TYPE_SIZE(struct seccomp_notif_resp, 24);
      82  	struct seccomp_notif_resp resp;
      83  
      84  	if (umove_or_printaddr(tcp, addr, &resp))
      85  		return;
      86  
      87  	tprint_struct_begin();
      88  	PRINT_FIELD_X(resp, id);
      89  	tprint_struct_next();
      90  	PRINT_FIELD_D(resp, val);
      91  	tprint_struct_next();
      92  	PRINT_FIELD_ERR_D(resp, error);
      93  	tprint_struct_next();
      94  	PRINT_FIELD_FLAGS(resp, flags, seccomp_ioctl_resp_flags,
      95  			  "SECCOMP_USER_NOTIF_FLAG_???");
      96  	tprint_struct_end();
      97  }
      98  
      99  static void
     100  print_struct_seccomp_notif_addfd(struct tcb *const tcp,
     101  				 const kernel_ulong_t addr)
     102  {
     103  	CHECK_IOCTL_SIZE(SECCOMP_IOCTL_NOTIF_ADDFD, 24);
     104  	CHECK_TYPE_SIZE(struct seccomp_notif_addfd, 24);
     105  	struct seccomp_notif_addfd addfd;
     106  
     107  	if (umove_or_printaddr(tcp, addr, &addfd))
     108  		return;
     109  
     110  	tprint_struct_begin();
     111  	PRINT_FIELD_X(addfd, id);
     112  	tprint_struct_next();
     113  	PRINT_FIELD_FLAGS(addfd, flags, seccomp_ioctl_addfd_flags,
     114  			  "SECCOMP_ADDFD_FLAG_???");
     115  	tprint_struct_next();
     116  	PRINT_FIELD_FD(addfd, srcfd, tcp);
     117  	tprint_struct_next();
     118  	PRINT_FIELD_D(addfd, newfd);
     119  	tprint_struct_next();
     120  	PRINT_FIELD_FLAGS(addfd, newfd_flags, open_mode_flags, "O_???");
     121  	tprint_struct_end();
     122  }
     123  
     124  int
     125  seccomp_ioctl(struct tcb *const tcp, const unsigned int code,
     126  	     const kernel_ulong_t arg)
     127  {
     128  	switch (code) {
     129  	case SECCOMP_IOCTL_NOTIF_RECV:
     130  		if (entering(tcp))
     131  			tprint_arg_next();
     132  
     133  		return print_struct_seccomp_notif(tcp, arg);
     134  
     135  	case SECCOMP_IOCTL_NOTIF_SEND:
     136  		tprint_arg_next();
     137  		print_struct_seccomp_notif_resp(tcp, arg);
     138  
     139  		return RVAL_IOCTL_DECODED;
     140  
     141  	case SECCOMP_IOCTL_NOTIF_ID_VALID_WRONG_DIR:
     142  	case SECCOMP_IOCTL_NOTIF_ID_VALID:
     143  		tprint_arg_next();
     144  		printnum_int64(tcp, arg, "%#" PRIx64);
     145  
     146  		return RVAL_IOCTL_DECODED;
     147  
     148  	case SECCOMP_IOCTL_NOTIF_ADDFD:
     149  		tprint_arg_next();
     150  		print_struct_seccomp_notif_addfd(tcp, arg);
     151  
     152  		return RVAL_IOCTL_DECODED;
     153  
     154  	default:
     155  		return RVAL_DECODED;
     156  	}
     157  }