Brooklyn/tools/testing/selftests/x86/syscall_numbering.c

90 lines
2.1 KiB
C
Raw Normal View History

2021-05-26 19:09:36 +00:00
/* SPDX-License-Identifier: GPL-2.0 */
/*
2021-09-23 16:59:15 +00:00
* syscall_arg_fault.c - tests faults 32-bit fast syscall stack args
2021-05-26 19:09:36 +00:00
* Copyright (c) 2018 Andrew Lutomirski
*/
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
2021-09-23 16:59:15 +00:00
#include <syscall.h>
2021-05-26 19:09:36 +00:00
2021-09-23 16:59:15 +00:00
static int nerrs;
2021-05-26 19:09:36 +00:00
2021-09-23 16:59:15 +00:00
#define X32_BIT 0x40000000UL
2021-05-26 19:09:36 +00:00
2021-09-23 16:59:15 +00:00
static void check_enosys(unsigned long nr, bool *ok)
2021-07-22 16:18:54 +00:00
{
2021-09-23 16:59:15 +00:00
/* If this fails, a segfault is reasonably likely. */
fflush(stdout);
2021-07-22 16:18:54 +00:00
2021-09-23 16:59:15 +00:00
long ret = syscall(nr, 0, 0, 0, 0, 0, 0);
if (ret == 0) {
printf("[FAIL]\tsyscall %lu succeeded, but it should have failed\n", nr);
*ok = false;
} else if (errno != ENOSYS) {
printf("[FAIL]\tsyscall %lu had error code %d, but it should have reported ENOSYS\n", nr, errno);
*ok = false;
}
2021-05-26 19:09:36 +00:00
}
2021-09-23 16:59:15 +00:00
static void test_x32_without_x32_bit(void)
2021-05-26 19:09:36 +00:00
{
2021-09-23 16:59:15 +00:00
bool ok = true;
2021-05-26 19:09:36 +00:00
/*
2021-09-23 16:59:15 +00:00
* Syscalls 512-547 are "x32" syscalls. They are intended to be
* called with the x32 (0x40000000) bit set. Calling them without
* the x32 bit set is nonsense and should not work.
2021-05-26 19:09:36 +00:00
*/
2021-09-23 16:59:15 +00:00
printf("[RUN]\tChecking syscalls 512-547\n");
for (int i = 512; i <= 547; i++)
check_enosys(i, &ok);
2021-05-26 19:09:36 +00:00
/*
2021-09-23 16:59:15 +00:00
* Check that a handful of 64-bit-only syscalls are rejected if the x32
* bit is set.
2021-05-26 19:09:36 +00:00
*/
2021-09-23 16:59:15 +00:00
printf("[RUN]\tChecking some 64-bit syscalls in x32 range\n");
check_enosys(16 | X32_BIT, &ok); /* ioctl */
check_enosys(19 | X32_BIT, &ok); /* readv */
check_enosys(20 | X32_BIT, &ok); /* writev */
2021-05-26 19:09:36 +00:00
/*
2021-09-23 16:59:15 +00:00
* Check some syscalls with high bits set.
2021-05-26 19:09:36 +00:00
*/
2021-09-23 16:59:15 +00:00
printf("[RUN]\tChecking numbers above 2^32-1\n");
check_enosys((1UL << 32), &ok);
check_enosys(X32_BIT | (1UL << 32), &ok);
2021-05-26 19:09:36 +00:00
2021-09-23 16:59:15 +00:00
if (!ok)
nerrs++;
else
printf("[OK]\tThey all returned -ENOSYS\n");
2021-07-22 16:18:54 +00:00
}
2021-09-23 16:59:15 +00:00
int main()
2021-07-22 16:18:54 +00:00
{
2021-05-26 19:09:36 +00:00
/*
2021-09-23 16:59:15 +00:00
* Anyone diagnosing a failure will want to know whether the kernel
* supports x32. Tell them.
2021-05-26 19:09:36 +00:00
*/
2021-09-23 16:59:15 +00:00
printf("\tChecking for x32...");
fflush(stdout);
if (syscall(39 | X32_BIT, 0, 0, 0, 0, 0, 0) >= 0) {
printf(" supported\n");
} else if (errno == ENOSYS) {
printf(" not supported\n");
2021-05-26 19:09:36 +00:00
} else {
2021-09-23 16:59:15 +00:00
printf(" confused\n");
2021-05-26 19:09:36 +00:00
}
2021-09-23 16:59:15 +00:00
test_x32_without_x32_bit();
2021-05-26 19:09:36 +00:00
2021-09-23 16:59:15 +00:00
return nerrs ? 1 : 0;
2021-05-26 19:09:36 +00:00
}