* [LTP] [PATCH 1/1] lib: dirtyc0w_shmem: userfaultfd01: Add safe_userfaultfd()
@ 2025-10-30 19:25 Petr Vorel
2025-11-05 8:46 ` Wei Gao via ltp
2025-12-18 11:58 ` Andrea Cervesato via ltp
0 siblings, 2 replies; 6+ messages in thread
From: Petr Vorel @ 2025-10-30 19:25 UTC (permalink / raw)
To: ltp
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);
+ }
+
+ 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
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [LTP] [PATCH 1/1] lib: dirtyc0w_shmem: userfaultfd01: Add safe_userfaultfd()
2025-10-30 19:25 [LTP] [PATCH 1/1] lib: dirtyc0w_shmem: userfaultfd01: Add safe_userfaultfd() Petr Vorel
@ 2025-11-05 8:46 ` Wei Gao via ltp
2025-11-05 10:30 ` Cyril Hrubis
2025-12-18 11:58 ` Andrea Cervesato via ltp
1 sibling, 1 reply; 6+ messages in thread
From: Wei Gao via ltp @ 2025-11-05 8:46 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
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
>
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [LTP] [PATCH 1/1] lib: dirtyc0w_shmem: userfaultfd01: Add safe_userfaultfd()
2025-11-05 8:46 ` Wei Gao via ltp
@ 2025-11-05 10:30 ` Cyril Hrubis
2025-11-05 12:05 ` Wei Gao via ltp
0 siblings, 1 reply; 6+ messages in thread
From: Cyril Hrubis @ 2025-11-05 10:30 UTC (permalink / raw)
To: Wei Gao; +Cc: ltp
Hi!
> > + } 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 ?
We are testing kernel and we have to check for situation that are
impossible under normal operation. There have been cases when a bug in a
kernel patch caused the syscall to return invalid return values, so we
are making extra sure that this does not happen.
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [LTP] [PATCH 1/1] lib: dirtyc0w_shmem: userfaultfd01: Add safe_userfaultfd()
2025-11-05 10:30 ` Cyril Hrubis
@ 2025-11-05 12:05 ` Wei Gao via ltp
0 siblings, 0 replies; 6+ messages in thread
From: Wei Gao via ltp @ 2025-11-05 12:05 UTC (permalink / raw)
To: Cyril Hrubis; +Cc: ltp
On Wed, Nov 05, 2025 at 11:30:19AM +0100, Cyril Hrubis wrote:
> Hi!
> > > + } 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 ?
>
> We are testing kernel and we have to check for situation that are
> impossible under normal operation. There have been cases when a bug in a
> kernel patch caused the syscall to return invalid return values, so we
> are making extra sure that this does not happen.
Thanks for the explanation.
Reviewed-by: Wei Gao <wegao@suse.com>
>
> --
> Cyril Hrubis
> chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH 1/1] lib: dirtyc0w_shmem: userfaultfd01: Add safe_userfaultfd()
2025-10-30 19:25 [LTP] [PATCH 1/1] lib: dirtyc0w_shmem: userfaultfd01: Add safe_userfaultfd() Petr Vorel
2025-11-05 8:46 ` Wei Gao via ltp
@ 2025-12-18 11:58 ` Andrea Cervesato via ltp
2025-12-22 12:05 ` Petr Vorel
1 sibling, 1 reply; 6+ messages in thread
From: Andrea Cervesato via ltp @ 2025-12-18 11:58 UTC (permalink / raw)
To: Petr Vorel, ltp
Hi!
Feel free to merge.
Reviewed-by: Andrea Cervesato <andrea.cervesato@suse.com>
--
Andrea Cervesato
SUSE QE Automation Engineer Linux
andrea.cervesato@suse.com
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-12-22 12:06 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-30 19:25 [LTP] [PATCH 1/1] lib: dirtyc0w_shmem: userfaultfd01: Add safe_userfaultfd() Petr Vorel
2025-11-05 8:46 ` Wei Gao via ltp
2025-11-05 10:30 ` Cyril Hrubis
2025-11-05 12:05 ` Wei Gao via ltp
2025-12-18 11:58 ` Andrea Cervesato via ltp
2025-12-22 12:05 ` Petr Vorel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox