1 /*
2 * Check decoding of userfaultfd syscall.
3 *
4 * Copyright (c) 2015-2018 Dmitry V. Levin <ldv@strace.io>
5 * Copyright (c) 2015-2021 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 "scno.h"
13
14 #include <stdio.h>
15 #include <unistd.h>
16 #include "kernel_fcntl.h"
17
18 #define UFFD_USER_MODE_ONLY 1
19
20 static const char *errstr;
21
22 static long
23 k_userfaultfd(const unsigned int flags)
24 {
25 const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
26 const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
27 const kernel_ulong_t arg1 = fill | flags;
28 const long rc = syscall(__NR_userfaultfd, arg1, bad, bad, bad, bad, bad);
29 errstr = sprintrc(rc);
30 return rc;
31 }
32
33 int
34 main(void)
35 {
36 struct {
37 unsigned int val;
38 const char *str;
39 } flags[] = {
40 { ARG_STR(0) },
41 { ARG_STR(O_NONBLOCK) },
42 { ARG_STR(O_CLOEXEC) },
43 { ARG_STR(O_NONBLOCK|O_CLOEXEC) },
44 { ARG_STR(UFFD_USER_MODE_ONLY) },
45 { ARG_STR(UFFD_USER_MODE_ONLY|O_NONBLOCK) },
46 { ARG_STR(UFFD_USER_MODE_ONLY|O_CLOEXEC) },
47 { ARG_STR(UFFD_USER_MODE_ONLY|O_NONBLOCK|O_CLOEXEC) },
48 };
49
50 for (unsigned int i = 0; i < ARRAY_SIZE(flags); ++i) {
51 k_userfaultfd(flags[i].val);
52 printf("userfaultfd(%s) = %s\n", flags[i].str, errstr);
53 }
54
55 k_userfaultfd(-1U);
56 printf("userfaultfd(UFFD_USER_MODE_ONLY|O_NONBLOCK|O_CLOEXEC|%#x)"
57 " = %s\n", (-1U - UFFD_USER_MODE_ONLY - O_NONBLOCK - O_CLOEXEC),
58 errstr);
59
60 puts("+++ exited with 0 +++");
61 return 0;
62 }