[PATCH v16 1/2] futex_wake05: Add EFAULT error coverage test
Michael Menasherov via ltp <[email protected]>
| Newsgroups | gmane.linux.ltp |
|---|---|
| Message-ID | <[email protected]> |
futex(FUTEX_WAKE) has no existing test for EFAULT. Add coverage for unmapped, PROT_NONE, and kernel-space uaddr, each exercising a different code path in the kernel's address validation. Signed-off-by: Michael Menasherov <[email protected]> --- runtest/syscalls | 1 + testcases/kernel/syscalls/futex/.gitignore | 1 + .../kernel/syscalls/futex/futex_wake05.c | 100 ++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 testcases/kernel/syscalls/futex/futex_wake05.c diff --git a/runtest/syscalls b/runtest/syscalls index a021c79da..67509826f 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -1878,6 +1878,7 @@ futex_wake01 futex_wake01 futex_wake02 futex_wake02 futex_wake03 futex_wake03 futex_wake04 futex_wake04 +futex_wake05 futex_wake05 futex_wait_bitset01 futex_wait_bitset01 memfd_create01 memfd_create01 diff --git a/testcases/kernel/syscalls/futex/.gitignore b/testcases/kernel/syscalls/futex/.gitignore index 74ac9a926..c11546e07 100644 --- a/testcases/kernel/syscalls/futex/.gitignore +++ b/testcases/kernel/syscalls/futex/.gitignore @@ -15,3 +15,4 @@ /futex_waitv03 /futex_wait06 /futex_wait07 +/futex_wake05 diff --git a/testcases/kernel/syscalls/futex/futex_wake05.c b/testcases/kernel/syscalls/futex/futex_wake05.c new file mode 100644 index 000000000..597426f0a --- /dev/null +++ b/testcases/kernel/syscalls/futex/futex_wake05.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2026 Red Hat, Inc. + * Copyright (C) 2026 Michael Menasherov <[email protected]> + */ + +/*\ + * Check that futex(FUTEX_WAKE) returns EFAULT when uaddr points to + * unmapped, PROT_NONE, or kernel-space memory. + * + * For opflags=0 (no FUTEX_PRIVATE_FLAG) futex_wake() takes the + * shared-futex path in get_futex_key() which must resolve the physical + * page. + * + * The three cases exercise different code paths: a kernel-space address + * is rejected by the kernel's user-space address check before physical + * page resolution; unmapped memory fails at find_vma() (no VMA exists); + * PROT_NONE memory fails at get_user_pages_fast() (VMA exists but page + * is inaccessible). + */ + +#include <errno.h> +#include <sys/mman.h> + +#include "futextest.h" + +static futex_t *unmapped_addr; +static futex_t *prot_none_addr; +static futex_t *kernel_addr = (futex_t *)-1L; + +static struct futex_test_variants variants[] = { +#if (__NR_futex != __LTP__NR_INVALID_SYSCALL) + { .fntype = FUTEX_FN_FUTEX, .desc = "syscall with old kernel spec"}, +#endif + +#if (__NR_futex_time64 != __LTP__NR_INVALID_SYSCALL) + { .fntype = FUTEX_FN_FUTEX64, .desc = "syscall time64 with kernel spec"}, +#endif +}; + +static struct testcase { + const char *desc; + futex_t **addr; + int exp_errno; +} testcases[] = { + { + .desc = "uaddr unmapped", + .addr = &unmapped_addr, + .exp_errno = EFAULT, + }, + { + .desc = "uaddr PROT_NONE", + .addr = &prot_none_addr, + .exp_errno = EFAULT, + }, + { + .desc = "uaddr kernel address", + .addr = &kernel_addr, + .exp_errno = EFAULT, + }, +}; + +static void run(unsigned int n) +{ + struct futex_test_variants *tv = &variants[tst_variant]; + struct testcase *tc = &testcases[n]; + + TST_EXP_FAIL(futex_wake(tv->fntype, *tc->addr, 1, 0), + tc->exp_errno, "%s", tc->desc); +} + +static void setup(void) +{ + struct futex_test_variants *tv = &variants[tst_variant]; + size_t pagesize = getpagesize(); + + tst_res(TINFO, "Testing variant: %s", tv->desc); + futex_supported_by_kernel(tv->fntype); + + unmapped_addr = SAFE_MMAP(NULL, pagesize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + SAFE_MUNMAP((void *)unmapped_addr, pagesize); + + prot_none_addr = SAFE_MMAP(NULL, pagesize, PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +} + +static void cleanup(void) +{ + if (prot_none_addr) + SAFE_MUNMAP((void *)prot_none_addr, getpagesize()); +} + +static struct tst_test test = { + .setup = setup, + .cleanup = cleanup, + .test = run, + .tcnt = ARRAY_SIZE(testcases), + .test_variants = ARRAY_SIZE(variants), +}; -- 2.54.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp