(root)/
strace-6.5/
tests-m32/
aio_pgetevents.c
       1  /*
       2   * Check decoding of io_pgetevents syscall.
       3   *
       4   * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2015-2023 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  #include <unistd.h>
      13  #include "scno.h"
      14  
      15  #ifdef __NR_io_pgetevents
      16  
      17  # include <fcntl.h>
      18  # include <inttypes.h>
      19  # include <stdio.h>
      20  # include <time.h>
      21  
      22  # include "nsig.h"
      23  
      24  # include <linux/aio_abi.h>
      25  
      26  # ifndef HAVE_STRUCT___AIO_SIGSET
      27  struct __aio_sigset {
      28  	sigset_t *sigmask;
      29  	size_t sigsetsize;
      30  };
      31  # endif
      32  
      33  static const char *errstr;
      34  
      35  static long
      36  sys_io_pgetevents(const kernel_ulong_t ctx_id,
      37  		  const kernel_long_t min_nr,
      38  		  const kernel_long_t nr,
      39  		  const kernel_ulong_t events,
      40  		  const kernel_ulong_t timeout,
      41  		  const kernel_ulong_t usig)
      42  {
      43  	long rc = syscall(__NR_io_pgetevents, ctx_id, min_nr, nr,
      44  			  events, timeout, usig);
      45  	errstr = sprintrc(rc);
      46  	return rc;
      47  }
      48  
      49  int
      50  main(void)
      51  {
      52  	static const kernel_ulong_t bogus_ctx =
      53  		(kernel_ulong_t) 0xface1e55deadbeefLL;
      54  	static const kernel_long_t bogus_min_nr =
      55  		(kernel_long_t) 0xca7faceddeadf00dLL;
      56  	static const kernel_long_t bogus_nr =
      57  		(kernel_long_t) 0xba5e1e505ca571e0LL;
      58  	static const size_t bogus_sigsetsize =
      59  		(size_t) 0xdeadbeefbadcaffeULL;
      60  
      61  	const unsigned int sizeof_data0 = 4096;
      62  	const unsigned int sizeof_data1 = 8192;
      63  	void *data0 = tail_alloc(sizeof_data0);
      64  	void *data1 = tail_alloc(sizeof_data1);
      65  
      66  	const struct iocb proto_cb[] = {
      67  		{
      68  			.aio_data = (unsigned long) 0xfeedface11111111ULL,
      69  			.aio_reqprio = 11,
      70  			.aio_buf = (unsigned long) data0,
      71  			.aio_offset = (unsigned long) 0xdeface1facefeedULL,
      72  			.aio_nbytes = sizeof_data0
      73  		},
      74  		{
      75  			.aio_data = (unsigned long) 0xfeedface22222222ULL,
      76  			.aio_reqprio = 22,
      77  			.aio_buf = (unsigned long) data1,
      78  			.aio_offset = (unsigned long) 0xdeface2cafef00dULL,
      79  			.aio_nbytes = sizeof_data1
      80  		}
      81  	};
      82  	const struct iocb *cb = tail_memdup(proto_cb, sizeof(proto_cb));
      83  
      84  	const long proto_cbs[] = {
      85  		(long) &cb[0], (long) &cb[1]
      86  	};
      87  	const long *cbs = tail_memdup(proto_cbs, sizeof(proto_cbs));
      88  
      89  	TAIL_ALLOC_OBJECT_CONST_PTR(unsigned long, ctx);
      90  	*ctx = 0;
      91  
      92  	const unsigned int nr = ARRAY_SIZE(proto_cb);
      93  
      94  	const struct io_event *ev = tail_alloc(nr * sizeof(struct io_event));
      95  	TAIL_ALLOC_OBJECT_CONST_PTR(kernel_old_timespec_t, ts);
      96  	TAIL_ALLOC_OBJECT_CONST_PTR(struct __aio_sigset, ss);
      97  	TAIL_ALLOC_OBJECT_CONST_PTR(sigset_t, sigs);
      98  
      99  	(void) close(0);
     100  	if (open("/dev/zero", O_RDONLY))
     101  		perror_msg_and_skip("open: %s", "/dev/zero");
     102  
     103  	if (syscall(__NR_io_setup, nr, ctx))
     104  		perror_msg_and_skip("io_setup");
     105  
     106  	if (syscall(__NR_io_submit, *ctx, nr, cbs) != (long) nr)
     107  		perror_msg_and_skip("io_submit");
     108  
     109  	sys_io_pgetevents(bogus_ctx, bogus_min_nr, bogus_nr,
     110  			  (uintptr_t) (ev + 1), 0, 0);
     111  	printf("io_pgetevents(%#jx, %ld, %ld, %p, NULL, NULL) = %s\n",
     112  	       (uintmax_t) bogus_ctx, (long) bogus_min_nr,
     113  	       (long) bogus_nr, ev + 1, errstr);
     114  
     115  	sys_io_pgetevents(bogus_ctx, bogus_min_nr, bogus_nr,
     116  			  0, (uintptr_t) (ts + 1), 0);
     117  	printf("io_pgetevents(%#jx, %ld, %ld, NULL, %p, NULL) = %s\n",
     118  	       (uintmax_t) bogus_ctx, (long) bogus_min_nr,
     119  	       (long) bogus_nr, ts + 1, errstr);
     120  
     121  	sys_io_pgetevents(bogus_ctx, bogus_min_nr, bogus_nr,
     122  			  0, 0, (uintptr_t) (ss + 1));
     123  	printf("io_pgetevents(%#jx, %ld, %ld, NULL, NULL, %p) = %s\n",
     124  	       (uintmax_t) bogus_ctx, (long) bogus_min_nr,
     125  	       (long) bogus_nr, ss + 1, errstr);
     126  
     127  	ss->sigmask = sigs + 1;
     128  	ss->sigsetsize =  bogus_sigsetsize;
     129  	sys_io_pgetevents(bogus_ctx, bogus_min_nr, bogus_nr,
     130  			  0, 0, (uintptr_t) ss);
     131  	printf("io_pgetevents(%#jx, %ld, %ld, NULL, NULL"
     132  	       ", {sigmask=%p, sigsetsize=%zu}) = %s\n",
     133  	       (uintmax_t) bogus_ctx, (long) bogus_min_nr,
     134  	       (long) bogus_nr, sigs + 1, bogus_sigsetsize, errstr);
     135  
     136  	ts->tv_sec = 0xdeadbeefU;
     137  	ts->tv_nsec = 0xfacefeedU;
     138  	ss->sigmask = sigs;
     139  	ss->sigsetsize =  NSIG_BYTES;
     140  	sys_io_pgetevents(bogus_ctx, 0, 0, 0, (uintptr_t) ts, (uintptr_t) ss);
     141  	printf("io_pgetevents(%#jx, 0, 0, NULL"
     142  	       ", {tv_sec=%lld, tv_nsec=%llu}"
     143  	       ", {sigmask=~[], sigsetsize=%u}) = %s\n",
     144  	       (uintmax_t) bogus_ctx, (long long) ts->tv_sec,
     145  	       zero_extend_signed_to_ull(ts->tv_nsec), NSIG_BYTES,
     146  	       errstr);
     147  
     148  	sigemptyset(sigs);
     149  	sigaddset(sigs, SIGSYS);
     150  
     151  	ts->tv_sec = (typeof(ts->tv_sec)) 0xcafef00ddeadbeefLL;
     152  	ts->tv_nsec = (long) 0xbadc0dedfacefeedLL;
     153  	sys_io_pgetevents(bogus_ctx, 0, 0, 0, (uintptr_t) ts, (uintptr_t) ss);
     154  	printf("io_pgetevents(%#jx, 0, 0, NULL"
     155  	       ", {tv_sec=%lld, tv_nsec=%llu}"
     156  	       ", {sigmask=[SYS], sigsetsize=%u}) = %s\n",
     157  	       (uintmax_t) bogus_ctx, (long long) ts->tv_sec,
     158  	       zero_extend_signed_to_ull(ts->tv_nsec), NSIG_BYTES,
     159  	       errstr);
     160  
     161  	puts("+++ exited with 0 +++");
     162  	return 0;
     163  }
     164  
     165  #else
     166  
     167  SKIP_MAIN_UNDEFINED("__NR_io_pgetevents")
     168  
     169  #endif