[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