Merge branch 'x86-entry-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 entry updates from Ingo Molnar: "This contains x32 and compat syscall improvements, the biggest one of which splits x32 syscalls into their own table, which allows new syscalls to share the x32 and x86-64 number - which turns the 512-547 special syscall numbers range into a legacy wart that won't be extended going forward" * 'x86-entry-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/syscalls: Split the x32 syscalls into their own table x86/syscalls: Disallow compat entries for all types of 64-bit syscalls x86/syscalls: Use the compat versions of rt_sigsuspend() and rt_sigprocmask() x86/syscalls: Make __X32_SYSCALL_BIT be unsigned long
This commit is contained in:
@@ -17,7 +17,7 @@ TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap
|
||||
TARGETS_C_32BIT_ONLY := entry_from_vm86 test_syscall_vdso unwind_vdso \
|
||||
test_FCMOV test_FCOMI test_FISTTP \
|
||||
vdso_restorer
|
||||
TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip
|
||||
TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip syscall_numbering
|
||||
# Some selftests require 32bit support enabled also on 64bit systems
|
||||
TARGETS_C_32BIT_NEEDED := ldt_gdt ptrace_syscall
|
||||
|
||||
|
89
tools/testing/selftests/x86/syscall_numbering.c
Normal file
89
tools/testing/selftests/x86/syscall_numbering.c
Normal file
@@ -0,0 +1,89 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* syscall_arg_fault.c - tests faults 32-bit fast syscall stack args
|
||||
* Copyright (c) 2018 Andrew Lutomirski
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <syscall.h>
|
||||
|
||||
static int nerrs;
|
||||
|
||||
#define X32_BIT 0x40000000UL
|
||||
|
||||
static void check_enosys(unsigned long nr, bool *ok)
|
||||
{
|
||||
/* If this fails, a segfault is reasonably likely. */
|
||||
fflush(stdout);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_x32_without_x32_bit(void)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
printf("[RUN]\tChecking syscalls 512-547\n");
|
||||
for (int i = 512; i <= 547; i++)
|
||||
check_enosys(i, &ok);
|
||||
|
||||
/*
|
||||
* Check that a handful of 64-bit-only syscalls are rejected if the x32
|
||||
* bit is set.
|
||||
*/
|
||||
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 */
|
||||
|
||||
/*
|
||||
* Check some syscalls with high bits set.
|
||||
*/
|
||||
printf("[RUN]\tChecking numbers above 2^32-1\n");
|
||||
check_enosys((1UL << 32), &ok);
|
||||
check_enosys(X32_BIT | (1UL << 32), &ok);
|
||||
|
||||
if (!ok)
|
||||
nerrs++;
|
||||
else
|
||||
printf("[OK]\tThey all returned -ENOSYS\n");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
/*
|
||||
* Anyone diagnosing a failure will want to know whether the kernel
|
||||
* supports x32. Tell them.
|
||||
*/
|
||||
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");
|
||||
} else {
|
||||
printf(" confused\n");
|
||||
}
|
||||
|
||||
test_x32_without_x32_bit();
|
||||
|
||||
return nerrs ? 1 : 0;
|
||||
}
|
Reference in New Issue
Block a user