1 /* SPDX-License-Identifier: GPL-2.0 */
3 * syscall_arg_fault.c - tests faults 32-bit fast syscall stack args
4 * Copyright (c) 2018 Andrew Lutomirski
18 #define X32_BIT 0x40000000UL
20 static void check_enosys(unsigned long nr
, bool *ok
)
22 /* If this fails, a segfault is reasonably likely. */
25 long ret
= syscall(nr
, 0, 0, 0, 0, 0, 0);
27 printf("[FAIL]\tsyscall %lu succeeded, but it should have failed\n", nr
);
29 } else if (errno
!= ENOSYS
) {
30 printf("[FAIL]\tsyscall %lu had error code %d, but it should have reported ENOSYS\n", nr
, errno
);
35 static void test_x32_without_x32_bit(void)
40 * Syscalls 512-547 are "x32" syscalls. They are intended to be
41 * called with the x32 (0x40000000) bit set. Calling them without
42 * the x32 bit set is nonsense and should not work.
44 printf("[RUN]\tChecking syscalls 512-547\n");
45 for (int i
= 512; i
<= 547; i
++)
49 * Check that a handful of 64-bit-only syscalls are rejected if the x32
52 printf("[RUN]\tChecking some 64-bit syscalls in x32 range\n");
53 check_enosys(16 | X32_BIT
, &ok
); /* ioctl */
54 check_enosys(19 | X32_BIT
, &ok
); /* readv */
55 check_enosys(20 | X32_BIT
, &ok
); /* writev */
58 * Check some syscalls with high bits set.
60 printf("[RUN]\tChecking numbers above 2^32-1\n");
61 check_enosys((1UL << 32), &ok
);
62 check_enosys(X32_BIT
| (1UL << 32), &ok
);
67 printf("[OK]\tThey all returned -ENOSYS\n");
73 * Anyone diagnosing a failure will want to know whether the kernel
74 * supports x32. Tell them.
76 printf("\tChecking for x32...");
78 if (syscall(39 | X32_BIT
, 0, 0, 0, 0, 0, 0) >= 0) {
79 printf(" supported\n");
80 } else if (errno
== ENOSYS
) {
81 printf(" not supported\n");
83 printf(" confused\n");
86 test_x32_without_x32_bit();