From: Eugene Syromyatnikov Date: Wed, 13 Jun 2018 15:38:07 +0000 (+0200) Subject: tests: check decoding of io_pgetevents syscall X-Git-Tag: v4.23~7 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2cc81216cb462f1c39ac13b1510088177fa1352c;p=strace tests: check decoding of io_pgetevents syscall * configure.ac (AC_CHECK_TYPES): Check for struct __aio_sigset in . * tests/aio_pgetevents.c: New file. * tests/.gitignore: Add aio_pgetevents. * tests/pure_executables.list: Likewise. * tests/gen_tests.in (aio_pgetevents): New test. Co-Authored-by: Dmitry V. Levin --- diff --git a/configure.ac b/configure.ac index d0242bec..9dec1b23 100644 --- a/configure.ac +++ b/configure.ac @@ -580,6 +580,11 @@ AC_CHECK_TYPES(m4_normalize([ struct kvm_userspace_memory_region ]),,, [#include ]) +saved_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS -I$srcdir/linux" +AC_CHECK_TYPES([struct __aio_sigset],,, [#include ]) +CPPFLAGS="$saved_CPPFLAGS" + AC_CHECK_HEADERS([linux/btrfs.h], [ AC_CHECK_MEMBERS(m4_normalize([ struct btrfs_ioctl_feature_flags.compat_flags, diff --git a/tests/.gitignore b/tests/.gitignore index b42b1312..2285a357 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -12,6 +12,7 @@ acct add_key adjtimex aio +aio_pgetevents alarm answer attach-f-p diff --git a/tests/aio_pgetevents.c b/tests/aio_pgetevents.c new file mode 100644 index 00000000..ba5ac718 --- /dev/null +++ b/tests/aio_pgetevents.c @@ -0,0 +1,190 @@ +/* + * Check decoding of io_pgetevents syscall. + * + * Copyright (c) 2015-2016 Dmitry V. Levin + * Copyright (c) 2015-2018 The strace developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "tests.h" +#include +#include +#include "scno.h" + +#if defined __NR_io_setup && defined __NR_io_pgetevents + +# include +# include +# include +# include + +# include "nsig.h" + +# include + +# if !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); + + const struct io_event *ev = tail_alloc(nr * sizeof(struct io_event)); + TAIL_ALLOC_OBJECT_CONST_PTR(struct timespec, 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 = (time_t) 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_setup && __NR_io_pgetevents") + +#endif diff --git a/tests/gen_tests.in b/tests/gen_tests.in index 62d5e783..24e0510e 100644 --- a/tests/gen_tests.in +++ b/tests/gen_tests.in @@ -34,6 +34,7 @@ acct -a20 add_key -a30 -s12 adjtimex -a15 aio -a14 -e trace=io_setup,io_submit,io_getevents,io_cancel,io_destroy +aio_pgetevents -e trace=io_pgetevents alarm -a10 bpf -a20 bpf-v -a20 -v -e trace=bpf diff --git a/tests/pure_executables.list b/tests/pure_executables.list index 86676752..39565d0c 100755 --- a/tests/pure_executables.list +++ b/tests/pure_executables.list @@ -7,6 +7,7 @@ acct add_key adjtimex aio +aio_pgetevents alarm bpf bpf-v