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