[LTP] [PATCH 1/1] lib: dirtyc0w_shmem: userfaultfd01: Add safe_userfaultfd()
Wei Gao
wegao@suse.com
Wed Nov 5 09:46:01 CET 2025
On Thu, Oct 30, 2025 at 08:25:43PM +0100, Petr Vorel wrote:
> Use TINFO in tst_res() followed by tst_brk(TBROK, ...).
>
> Signed-off-by: Petr Vorel <pvorel@suse.cz>
> ---
> NOTE: SAFE_USERFAULTFD() could be used also in Wei's mremap07.c
> https://patchwork.ozlabs.org/project/ltp/patch/20251030054029.23511-1-wegao@suse.com/
>
> include/lapi/userfaultfd.h | 33 +++++++++++++++++++
> .../dirtyc0w_shmem/dirtyc0w_shmem_child.c | 15 +--------
> .../syscalls/userfaultfd/userfaultfd01.c | 18 +---------
> 3 files changed, 35 insertions(+), 31 deletions(-)
>
> diff --git a/include/lapi/userfaultfd.h b/include/lapi/userfaultfd.h
> index 4d52b7c4bb..8c9482c3d1 100644
> --- a/include/lapi/userfaultfd.h
> +++ b/include/lapi/userfaultfd.h
> @@ -2,6 +2,7 @@
> /*
> * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
> * Copyright (C) 2015,2022 Red Hat, Inc.
> + * Copyright (c) Linux Test Project, 2025
> *
> * Mostly copied/adapted from <linux/userfaultfd.h>
> */
> @@ -9,6 +10,7 @@
> #ifndef LAPI_USERFAULTFD_H__
> #define LAPI_USERFAULTFD_H__
>
> +#include <stdbool.h>
> #include <unistd.h>
> #include <sys/types.h>
> #include "lapi/syscalls.h"
> @@ -187,4 +189,35 @@ struct uffdio_continue {
> #define UFFD_FEATURE_MINOR_SHMEM (1<<10)
> #endif /* UFFD_FEATURE_MINOR_SHMEM */
>
> +#define SAFE_USERFAULTFD(flags, retry) \
> + safe_userfaultfd(__FILE__, __LINE__, (flags), (retry))
> +
> +static inline int safe_userfaultfd(const char *file, const int lineno, int
> + flags, bool retry)
> +{
> + int ret;
> +
> +retry:
> + ret = tst_syscall(__NR_userfaultfd, flags);
> + if (ret == -1) {
> + if (errno == EPERM) {
> + if (retry && !(flags & UFFD_USER_MODE_ONLY)) {
> + flags |= UFFD_USER_MODE_ONLY;
> + goto retry;
> + }
> + tst_res_(file, lineno, TINFO,
> + "Hint: check /proc/sys/vm/unprivileged_userfaultfd");
> + tst_brk_(file, lineno, TCONF | TERRNO,
> + "userfaultfd() requires CAP_SYS_PTRACE on this system");
> + }
> + tst_brk_(file, lineno, TBROK | TERRNO,
> + "syscall(__NR_userfaultfd, %d) failed", flags);
> + } else if (ret < 0) {
> + tst_brk_(file, lineno, TBROK | TERRNO,
> + "Invalid syscall(__NR_userfaultfd, %d) return value %d", flags, ret);
> + }
I suppose main error handle if (ret == -1) already cover standard syscall
error, why still need check ret < 0 ?
> +
> + return ret;
> +}
> +
> #endif /* LAPI_USERFAULTFD_H__ */
> diff --git a/testcases/kernel/security/dirtyc0w_shmem/dirtyc0w_shmem_child.c b/testcases/kernel/security/dirtyc0w_shmem/dirtyc0w_shmem_child.c
> index 2a982347c5..9c60fbfa34 100644
> --- a/testcases/kernel/security/dirtyc0w_shmem/dirtyc0w_shmem_child.c
> +++ b/testcases/kernel/security/dirtyc0w_shmem/dirtyc0w_shmem_child.c
> @@ -128,21 +128,8 @@ static void setup_uffd(void)
> {
> struct uffdio_register uffdio_register;
> struct uffdio_api uffdio_api;
> - int flags = O_CLOEXEC | O_NONBLOCK;
>
> -retry:
> - TEST(tst_syscall(__NR_userfaultfd, flags));
> - if (TST_RET < 0) {
> - if (TST_ERR == EPERM) {
> - if (!(flags & UFFD_USER_MODE_ONLY)) {
> - flags |= UFFD_USER_MODE_ONLY;
> - goto retry;
> - }
> - }
> - tst_brk(TBROK | TTERRNO,
> - "Could not create userfault file descriptor");
> - }
> - uffd = TST_RET;
> + uffd = SAFE_USERFAULTFD(O_CLOEXEC | O_NONBLOCK, true);
>
> uffdio_api.api = UFFD_API;
> uffdio_api.features = UFFD_FEATURE_MINOR_SHMEM;
> diff --git a/testcases/kernel/syscalls/userfaultfd/userfaultfd01.c b/testcases/kernel/syscalls/userfaultfd/userfaultfd01.c
> index c2c684d2b8..5a973ad8e9 100644
> --- a/testcases/kernel/syscalls/userfaultfd/userfaultfd01.c
> +++ b/testcases/kernel/syscalls/userfaultfd/userfaultfd01.c
> @@ -23,11 +23,6 @@ static char *page;
> static void *copy_page;
> static int uffd;
>
> -static int sys_userfaultfd(int flags)
> -{
> - return tst_syscall(__NR_userfaultfd, flags);
> -}
> -
> static void set_pages(void)
> {
> page_size = sysconf(_SC_PAGE_SIZE);
> @@ -80,19 +75,8 @@ static void run(void)
>
> set_pages();
>
> - TEST(sys_userfaultfd(O_CLOEXEC | O_NONBLOCK));
> -
> - if (TST_RET == -1) {
> - if (TST_ERR == EPERM) {
> - tst_res(TCONF, "Hint: check /proc/sys/vm/unprivileged_userfaultfd");
> - tst_brk(TCONF | TTERRNO,
> - "userfaultfd() requires CAP_SYS_PTRACE on this system");
> - } else
> - tst_brk(TBROK | TTERRNO,
> - "Could not create userfault file descriptor");
> - }
> + uffd = SAFE_USERFAULTFD(O_CLOEXEC | O_NONBLOCK, false);
>
> - uffd = TST_RET;
> uffdio_api.api = UFFD_API;
> uffdio_api.features = 0;
> SAFE_IOCTL(uffd, UFFDIO_API, &uffdio_api);
> --
> 2.51.0
>
More information about the ltp
mailing list