[LTP] [PATCH v16 1/2] futex_wake05: Add EFAULT error coverage test
Petr Vorel
pvorel@suse.cz
Fri Jul 3 10:32:15 CEST 2026
Hi Michael,
> 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.
Generally LGTM, few comments below.
> 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 <mmenashe@redhat.com>
> + */
> +
> +/*\
> + * 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).
nit: It'd be more readable using list:
* 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,
nit: If all errors are EFAULT why not use it directly in TST_EXP_FAIL?
But more important is that I got a different errno (EINVAL) on 7.0.x kernel on
old kernel spec:
futex_wake05.c:77: TINFO: Testing variant: syscall with old kernel spec
futex_wake05.c:68: TFAIL: uaddr kernel address expected EFAULT: EINVAL (22)
When compiling 32 bit, I get error on both specs:
PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig CFLAGS=-m32 LDFLAGS=-m32 ./configure
...
futex_wake05.c:77: TINFO: Testing variant: syscall with old kernel spec
futex_wake05.c:68: TPASS: uaddr unmapped : EFAULT (14)
futex_wake05.c:68: TPASS: uaddr PROT_NONE : EFAULT (14)
futex_wake05.c:68: TFAIL: uaddr kernel address expected EFAULT: EINVAL (22)
futex_wake05.c:77: TINFO: Testing variant: syscall time64 with kernel spec
futex_wake05.c:68: TPASS: uaddr unmapped : EFAULT (14)
futex_wake05.c:68: TPASS: uaddr PROT_NONE : EFAULT (14)
futex_wake05.c:68: TFAIL: uaddr kernel address expected EFAULT: EINVAL (22)
I tested very old kernel 4.4 (SLE12-SP3 we still support) and it behaves the
same. Do you really get EFAULT?
Kind regards,
Petr
More information about the ltp
mailing list