* [LTP] [PATCH 0/6] ioctl_pidfd testing suite
@ 2025-06-26 12:34 Andrea Cervesato
2025-06-26 12:34 ` [LTP] [PATCH 1/6] Provide pidfd parameter in tst_clone_args Andrea Cervesato
` (6 more replies)
0 siblings, 7 replies; 16+ messages in thread
From: Andrea Cervesato @ 2025-06-26 12:34 UTC (permalink / raw)
To: ltp
The testing suite has been created to cover the new feature
PIDFD_INFO_EXIT provided by kernel 6.15.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
Andrea Cervesato (6):
Provide pidfd parameter in tst_clone_args
Fallback PIDFD_GET_INFO related definitions
Add ioctl_pidfd01 test
Add ioctl_pidfd02 test
Add ioctl_pidfd03 test
Add ioctl_pidfd04 test
configure.ac | 2 +
include/lapi/pidfd.h | 37 ++++++++++++++
include/tst_clone.h | 1 +
lib/tst_clone.c | 1 +
runtest/syscalls | 5 ++
testcases/kernel/syscalls/ioctl/.gitignore | 4 ++
testcases/kernel/syscalls/ioctl/ioctl_pidfd01.c | 58 +++++++++++++++++++++
testcases/kernel/syscalls/ioctl/ioctl_pidfd02.c | 62 ++++++++++++++++++++++
testcases/kernel/syscalls/ioctl/ioctl_pidfd03.c | 50 ++++++++++++++++++
testcases/kernel/syscalls/ioctl/ioctl_pidfd04.c | 68 +++++++++++++++++++++++++
10 files changed, 288 insertions(+)
---
base-commit: 0c99c7915f029d32de893b15b0a213ff3de210af
change-id: 20250626-ioctl_pidfd_suite-322aa2375c42
Best regards,
--
Andrea Cervesato <andrea.cervesato@suse.com>
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 16+ messages in thread
* [LTP] [PATCH 1/6] Provide pidfd parameter in tst_clone_args
2025-06-26 12:34 [LTP] [PATCH 0/6] ioctl_pidfd testing suite Andrea Cervesato
@ 2025-06-26 12:34 ` Andrea Cervesato
2025-06-26 12:34 ` [LTP] [PATCH 2/6] Fallback PIDFD_GET_INFO related definitions Andrea Cervesato
` (5 subsequent siblings)
6 siblings, 0 replies; 16+ messages in thread
From: Andrea Cervesato @ 2025-06-26 12:34 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
include/tst_clone.h | 1 +
lib/tst_clone.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/include/tst_clone.h b/include/tst_clone.h
index a57d761ca56dc113dde81a0ed17f15e8f2e58924..a07689c78f575ae6ca87c0952b3e48b3a626012c 100644
--- a/include/tst_clone.h
+++ b/include/tst_clone.h
@@ -12,6 +12,7 @@
/* The parts of clone3's clone_args we support */
struct tst_clone_args {
uint64_t flags;
+ uint64_t pidfd;
uint64_t exit_signal;
uint64_t cgroup;
};
diff --git a/lib/tst_clone.c b/lib/tst_clone.c
index 2aa00beb1a191d8c4a68a96ba529fc48d3777e84..8638052e2ecac2af3a290f01106e10dc8cdc62d1 100644
--- a/lib/tst_clone.c
+++ b/lib/tst_clone.c
@@ -14,6 +14,7 @@ pid_t tst_clone(const struct tst_clone_args *tst_args)
{
struct clone_args args = {
.flags = tst_args->flags,
+ .pidfd = tst_args->pidfd,
.exit_signal = tst_args->exit_signal,
.cgroup = tst_args->cgroup,
};
--
2.50.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [LTP] [PATCH 2/6] Fallback PIDFD_GET_INFO related definitions
2025-06-26 12:34 [LTP] [PATCH 0/6] ioctl_pidfd testing suite Andrea Cervesato
2025-06-26 12:34 ` [LTP] [PATCH 1/6] Provide pidfd parameter in tst_clone_args Andrea Cervesato
@ 2025-06-26 12:34 ` Andrea Cervesato
2025-06-26 12:34 ` [LTP] [PATCH 3/6] Add ioctl_pidfd01 test Andrea Cervesato
` (4 subsequent siblings)
6 siblings, 0 replies; 16+ messages in thread
From: Andrea Cervesato @ 2025-06-26 12:34 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
configure.ac | 2 ++
include/lapi/pidfd.h | 37 +++++++++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/configure.ac b/configure.ac
index 69c5be7362a0e9f2fdaf3e6bd01f92f6f4880108..7132c00df97870e234fd5b8c9fcaf1beb263cf06 100644
--- a/configure.ac
+++ b/configure.ac
@@ -259,6 +259,8 @@ AC_CHECK_TYPES([struct cachestat],,,[#include <sys/mman.h>])
AC_CHECK_TYPES([struct mnt_id_req],,,[#include <sys/mount.h>])
AC_CHECK_TYPES([struct statmount],,,[#include <sys/mount.h>])
+AC_CHECK_TYPES([struct pidfd_info],,,[#include <uapi/linux/pidfd.h>])
+
# Tools knobs
# Bash
diff --git a/include/lapi/pidfd.h b/include/lapi/pidfd.h
index 9ca8e5aa23626646ebb2f18880abd5e52298bfc6..55a44d5840c01bda7b31237c5c0d54ebba8155c5 100644
--- a/include/lapi/pidfd.h
+++ b/include/lapi/pidfd.h
@@ -8,16 +8,53 @@
#define LAPI_PIDFD_H__
#include <fcntl.h>
+#include <stdint.h>
+#include <sys/ioctl.h>
+
#ifdef HAVE_SYS_PIDFD_H
# include <sys/pidfd.h>
#endif
+
#include "config.h"
#include "lapi/syscalls.h"
+#ifndef HAVE_STRUCT_PIDFD_INFO
+struct pidfd_info {
+ uint64_t mask;
+ uint64_t cgroupid;
+ uint32_t pid;
+ uint32_t tgid;
+ uint32_t ppid;
+ uint32_t ruid;
+ uint32_t rgid;
+ uint32_t euid;
+ uint32_t egid;
+ uint32_t suid;
+ uint32_t sgid;
+ uint32_t fsuid;
+ uint32_t fsgid;
+ int32_t exit_code;
+ uint32_t coredump_mask;
+ uint32_t __spare1;
+};
+#endif
+
#ifndef PIDFD_NONBLOCK
#define PIDFD_NONBLOCK O_NONBLOCK
#endif
+#ifndef PIDFS_IOCTL_MAGIC
+#define PIDFS_IOCTL_MAGIC 0xFF
+#endif
+
+#ifndef PIDFD_GET_INFO
+#define PIDFD_GET_INFO _IOWR(PIDFS_IOCTL_MAGIC, 11, struct pidfd_info)
+#endif
+
+#ifndef PIDFD_INFO_EXIT
+#define PIDFD_INFO_EXIT (1UL << 3)
+#endif
+
static inline void pidfd_send_signal_supported(void)
{
/* allow the tests to fail early */
--
2.50.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [LTP] [PATCH 3/6] Add ioctl_pidfd01 test
2025-06-26 12:34 [LTP] [PATCH 0/6] ioctl_pidfd testing suite Andrea Cervesato
2025-06-26 12:34 ` [LTP] [PATCH 1/6] Provide pidfd parameter in tst_clone_args Andrea Cervesato
2025-06-26 12:34 ` [LTP] [PATCH 2/6] Fallback PIDFD_GET_INFO related definitions Andrea Cervesato
@ 2025-06-26 12:34 ` Andrea Cervesato
2025-06-26 12:34 ` [LTP] [PATCH 4/6] Add ioctl_pidfd02 test Andrea Cervesato
` (3 subsequent siblings)
6 siblings, 0 replies; 16+ messages in thread
From: Andrea Cervesato @ 2025-06-26 12:34 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Verify that ioctl() raises the right errors when an application provides
the wrong file descriptor.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/syscalls | 2 +
testcases/kernel/syscalls/ioctl/.gitignore | 1 +
testcases/kernel/syscalls/ioctl/ioctl_pidfd01.c | 58 +++++++++++++++++++++++++
3 files changed, 61 insertions(+)
diff --git a/runtest/syscalls b/runtest/syscalls
index 582422ac9ca8ccae598c626a11cf6ee7c30f0e3a..7f6312ce5fa241a778d8dda7f8ee9edd0a8800e6 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -612,6 +612,8 @@ ioctl_ficlonerange01 ioctl_ficlonerange01
ioctl_ficlonerange02 ioctl_ficlonerange02
ioctl_fiemap01 ioctl_fiemap01
+ioctl_pidfd01 ioctl_pidfd01
+
inotify_init1_01 inotify_init1_01
inotify_init1_02 inotify_init1_02
diff --git a/testcases/kernel/syscalls/ioctl/.gitignore b/testcases/kernel/syscalls/ioctl/.gitignore
index 53a82bb5770ba196811965150fd262ec5d4a6e01..aa952c1a7bae0ae2dbb04de0595f10d508b6759a 100644
--- a/testcases/kernel/syscalls/ioctl/.gitignore
+++ b/testcases/kernel/syscalls/ioctl/.gitignore
@@ -29,3 +29,4 @@
/ioctl_ficlonerange01
/ioctl_ficlonerange02
/ioctl_fiemap01
+/ioctl_pidfd01
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_pidfd01.c b/testcases/kernel/syscalls/ioctl/ioctl_pidfd01.c
new file mode 100644
index 0000000000000000000000000000000000000000..dbece2b611ecea2e253bd5e784b196f4e0ee73f2
--- /dev/null
+++ b/testcases/kernel/syscalls/ioctl/ioctl_pidfd01.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Verify that ioctl() raises the right errors when an application provides
+ * the wrong file descriptor.
+ */
+
+#include "tst_test.h"
+#include "lapi/pidfd.h"
+#include "lapi/ioctl.h"
+
+static int exp_errnos[] = {
+ EINVAL,
+ EBADF,
+ ENOTTY,
+};
+
+static struct pidfd_info *info;
+
+static void test_bad_pidfd(struct tst_fd *fd_in)
+{
+ if (fd_in->type == TST_FD_PIDFD) {
+ tst_res(TINFO, "Skipping pidfd: SUCCESS");
+ return;
+ }
+
+ TST_EXP_FAIL_ARR(ioctl(fd_in->fd, PIDFD_GET_INFO, info),
+ exp_errnos, ARRAY_SIZE(exp_errnos),
+ "ioctl(%s, PIDFD_GET_INFO, info)",
+ tst_fd_desc(fd_in));
+}
+
+static void run(void)
+{
+ TST_FD_FOREACH(fd) {
+ tst_res(TINFO, "%s -> ...", tst_fd_desc(&fd));
+ test_bad_pidfd(&fd);
+ }
+}
+
+static void setup(void)
+{
+ info->mask = PIDFD_INFO_EXIT;
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .forks_child = 1,
+ .min_kver = "6.15",
+ .bufs = (struct tst_buffers []) {
+ {&info, .size = sizeof(*info)},
+ {}
+ }
+};
--
2.50.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [LTP] [PATCH 4/6] Add ioctl_pidfd02 test
2025-06-26 12:34 [LTP] [PATCH 0/6] ioctl_pidfd testing suite Andrea Cervesato
` (2 preceding siblings ...)
2025-06-26 12:34 ` [LTP] [PATCH 3/6] Add ioctl_pidfd01 test Andrea Cervesato
@ 2025-06-26 12:34 ` Andrea Cervesato
2025-06-27 9:11 ` Cyril Hrubis
2025-06-26 12:34 ` [LTP] [PATCH 5/6] Add ioctl_pidfd03 test Andrea Cervesato
` (2 subsequent siblings)
6 siblings, 1 reply; 16+ messages in thread
From: Andrea Cervesato @ 2025-06-26 12:34 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Check if the ioctl() function allows retrieval of a child's exit code
using PIDFD_INFO_EXIT from a process that is isolated from the child.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/ioctl/.gitignore | 1 +
testcases/kernel/syscalls/ioctl/ioctl_pidfd02.c | 62 +++++++++++++++++++++++++
3 files changed, 64 insertions(+)
diff --git a/runtest/syscalls b/runtest/syscalls
index 7f6312ce5fa241a778d8dda7f8ee9edd0a8800e6..23f335846663d62a39e6de3a8f6948c1b0acf8a5 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -613,6 +613,7 @@ ioctl_ficlonerange02 ioctl_ficlonerange02
ioctl_fiemap01 ioctl_fiemap01
ioctl_pidfd01 ioctl_pidfd01
+ioctl_pidfd02 ioctl_pidfd02
inotify_init1_01 inotify_init1_01
inotify_init1_02 inotify_init1_02
diff --git a/testcases/kernel/syscalls/ioctl/.gitignore b/testcases/kernel/syscalls/ioctl/.gitignore
index aa952c1a7bae0ae2dbb04de0595f10d508b6759a..1c81c2bed8db952af0c93fb1ce5bfbad82794b60 100644
--- a/testcases/kernel/syscalls/ioctl/.gitignore
+++ b/testcases/kernel/syscalls/ioctl/.gitignore
@@ -30,3 +30,4 @@
/ioctl_ficlonerange02
/ioctl_fiemap01
/ioctl_pidfd01
+/ioctl_pidfd02
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_pidfd02.c b/testcases/kernel/syscalls/ioctl/ioctl_pidfd02.c
new file mode 100644
index 0000000000000000000000000000000000000000..82dd8c359938cdc7bf69cc2fd6afc90ce2a95290
--- /dev/null
+++ b/testcases/kernel/syscalls/ioctl/ioctl_pidfd02.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Check if the ioctl() function allows retrieval of a child's exit code
+ * using PIDFD_INFO_EXIT from a process that is isolated from the child.
+ */
+
+#include "tst_test.h"
+#include "lapi/pidfd.h"
+#include "lapi/sched.h"
+
+static struct tst_clone_args *args;
+static struct pidfd_info *info;
+
+static void run(void)
+{
+ int status;
+ int pidfd = 0;
+ pid_t pid_child;
+
+ memset(args, 0, sizeof(struct tst_clone_args));
+
+ args->flags = CLONE_PIDFD | CLONE_NEWUSER | CLONE_NEWPID;
+ args->pidfd = (uint64_t)&pidfd;
+ args->exit_signal = SIGCHLD;
+
+ pid_child = SAFE_CLONE(args);
+ if (!pid_child) {
+ TST_CHECKPOINT_WAIT(0);
+ exit(100);
+ }
+
+ /* child is not reaped, so ioctl() will pass */
+ info->mask = 0;
+ SAFE_IOCTL(pidfd, PIDFD_GET_INFO, info);
+
+ TST_CHECKPOINT_WAKE(0);
+ SAFE_WAITPID(pid_child, &status, 0);
+
+ /* child is now reaped, so we can ask for the exit status */
+ info->mask = PIDFD_INFO_EXIT;
+ SAFE_IOCTL(pidfd, PIDFD_GET_INFO, info);
+
+ TST_EXP_EQ_LI(info->mask & PIDFD_INFO_EXIT, PIDFD_INFO_EXIT);
+ TST_EXP_EQ_LI(WIFEXITED(info->exit_code), WIFEXITED(status));
+ TST_EXP_EQ_LI(WEXITSTATUS(info->exit_code), WEXITSTATUS(status));
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .forks_child = 1,
+ .needs_checkpoints = 1,
+ .min_kver = "6.15",
+ .bufs = (struct tst_buffers []) {
+ {&args, .size = sizeof(*args)},
+ {&info, .size = sizeof(*info)},
+ {}
+ }
+};
--
2.50.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [LTP] [PATCH 5/6] Add ioctl_pidfd03 test
2025-06-26 12:34 [LTP] [PATCH 0/6] ioctl_pidfd testing suite Andrea Cervesato
` (3 preceding siblings ...)
2025-06-26 12:34 ` [LTP] [PATCH 4/6] Add ioctl_pidfd02 test Andrea Cervesato
@ 2025-06-26 12:34 ` Andrea Cervesato
2025-06-27 9:56 ` Cyril Hrubis
2025-06-26 12:34 ` [LTP] [PATCH 6/6] Add ioctl_pidfd04 test Andrea Cervesato
2025-06-27 10:14 ` [LTP] [PATCH 0/6] ioctl_pidfd testing suite Cyril Hrubis
6 siblings, 1 reply; 16+ messages in thread
From: Andrea Cervesato @ 2025-06-26 12:34 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Verify that ioctl() returns ESRCH when a process attempts to access
the exit status of an isolated child using `PIDFD_GET_INFO` and
`PIDFD_INFO_EXIT` is not defined in `struct pidfd_info`.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/ioctl/.gitignore | 1 +
testcases/kernel/syscalls/ioctl/ioctl_pidfd03.c | 50 +++++++++++++++++++++++++
3 files changed, 52 insertions(+)
diff --git a/runtest/syscalls b/runtest/syscalls
index 23f335846663d62a39e6de3a8f6948c1b0acf8a5..8eec613a941a83b1fed25f96cdce617da0b0ef34 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -614,6 +614,7 @@ ioctl_fiemap01 ioctl_fiemap01
ioctl_pidfd01 ioctl_pidfd01
ioctl_pidfd02 ioctl_pidfd02
+ioctl_pidfd03 ioctl_pidfd03
inotify_init1_01 inotify_init1_01
inotify_init1_02 inotify_init1_02
diff --git a/testcases/kernel/syscalls/ioctl/.gitignore b/testcases/kernel/syscalls/ioctl/.gitignore
index 1c81c2bed8db952af0c93fb1ce5bfbad82794b60..08387dc8f2bc43f8f3a75264841da4beee28bfac 100644
--- a/testcases/kernel/syscalls/ioctl/.gitignore
+++ b/testcases/kernel/syscalls/ioctl/.gitignore
@@ -31,3 +31,4 @@
/ioctl_fiemap01
/ioctl_pidfd01
/ioctl_pidfd02
+/ioctl_pidfd03
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_pidfd03.c b/testcases/kernel/syscalls/ioctl/ioctl_pidfd03.c
new file mode 100644
index 0000000000000000000000000000000000000000..0fef9e671d29f9a0a07e3f62973364cf365ac014
--- /dev/null
+++ b/testcases/kernel/syscalls/ioctl/ioctl_pidfd03.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Verify that ioctl() returns ESRCH when a process attempts to access the
+ * exit status of an isolated child using `PIDFD_GET_INFO` and
+ * `PIDFD_INFO_EXIT` is not defined in `struct pidfd_info`.
+ */
+
+#include "tst_test.h"
+#include "lapi/pidfd.h"
+#include "lapi/sched.h"
+
+static struct tst_clone_args *args;
+static struct pidfd_info *info;
+
+static void run(void)
+{
+ int status;
+ int pidfd = 0;
+ pid_t pid_child;
+
+ memset(args, 0, sizeof(struct tst_clone_args));
+
+ args->flags = CLONE_PIDFD | CLONE_NEWUSER | CLONE_NEWPID;
+ args->pidfd = (uint64_t)&pidfd;
+ args->exit_signal = SIGCHLD;
+
+ pid_child = SAFE_CLONE(args);
+ if (!pid_child)
+ exit(100);
+
+ SAFE_WAITPID(pid_child, &status, 0);
+
+ TST_EXP_FAIL(ioctl(pidfd, PIDFD_GET_INFO, info), ESRCH);
+ TST_EXP_EQ_LI(info->mask & PIDFD_INFO_EXIT, 0);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .forks_child = 1,
+ .min_kver = "6.15",
+ .bufs = (struct tst_buffers []) {
+ {&args, .size = sizeof(*args)},
+ {&info, .size = sizeof(*info)},
+ {}
+ }
+};
--
2.50.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [LTP] [PATCH 6/6] Add ioctl_pidfd04 test
2025-06-26 12:34 [LTP] [PATCH 0/6] ioctl_pidfd testing suite Andrea Cervesato
` (4 preceding siblings ...)
2025-06-26 12:34 ` [LTP] [PATCH 5/6] Add ioctl_pidfd03 test Andrea Cervesato
@ 2025-06-26 12:34 ` Andrea Cervesato
2025-06-27 10:14 ` [LTP] [PATCH 0/6] ioctl_pidfd testing suite Cyril Hrubis
6 siblings, 0 replies; 16+ messages in thread
From: Andrea Cervesato @ 2025-06-26 12:34 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Verify that ioctl() permits to obtain the exit code of an isolated
signaled child via PIDFD_INFO_EXIT from within a process.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/ioctl/.gitignore | 1 +
testcases/kernel/syscalls/ioctl/ioctl_pidfd04.c | 68 +++++++++++++++++++++++++
3 files changed, 70 insertions(+)
diff --git a/runtest/syscalls b/runtest/syscalls
index 8eec613a941a83b1fed25f96cdce617da0b0ef34..a28f4857ffccc070665361f2741ddbaa480d1153 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -615,6 +615,7 @@ ioctl_fiemap01 ioctl_fiemap01
ioctl_pidfd01 ioctl_pidfd01
ioctl_pidfd02 ioctl_pidfd02
ioctl_pidfd03 ioctl_pidfd03
+ioctl_pidfd04 ioctl_pidfd04
inotify_init1_01 inotify_init1_01
inotify_init1_02 inotify_init1_02
diff --git a/testcases/kernel/syscalls/ioctl/.gitignore b/testcases/kernel/syscalls/ioctl/.gitignore
index 08387dc8f2bc43f8f3a75264841da4beee28bfac..b6203828f324647ccf5d809e80e2ada515817006 100644
--- a/testcases/kernel/syscalls/ioctl/.gitignore
+++ b/testcases/kernel/syscalls/ioctl/.gitignore
@@ -32,3 +32,4 @@
/ioctl_pidfd01
/ioctl_pidfd02
/ioctl_pidfd03
+/ioctl_pidfd04
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_pidfd04.c b/testcases/kernel/syscalls/ioctl/ioctl_pidfd04.c
new file mode 100644
index 0000000000000000000000000000000000000000..be2db01171c338e85d544c058b79fb567e781a63
--- /dev/null
+++ b/testcases/kernel/syscalls/ioctl/ioctl_pidfd04.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Verify that ioctl() permits to obtain the exit code of an isolated signaled
+ * child via PIDFD_INFO_EXIT from within a process.
+ */
+
+#include "tst_test.h"
+#include "lapi/pidfd.h"
+#include "lapi/sched.h"
+
+static struct tst_clone_args *args;
+static struct pidfd_info *info;
+
+static void run(void)
+{
+ int status;
+ int pidfd = 0;
+ pid_t pid_child;
+
+ memset(args, 0, sizeof(struct tst_clone_args));
+
+ args->flags = CLONE_PIDFD | CLONE_NEWUSER | CLONE_NEWPID;
+ args->pidfd = (uint64_t)&pidfd;
+ args->exit_signal = SIGCHLD;
+
+ pid_child = SAFE_CLONE(args);
+ if (!pid_child) {
+ TST_CHECKPOINT_WAKE_AND_WAIT(0);
+ exit(1);
+ }
+
+ TST_CHECKPOINT_WAIT(0);
+
+ SAFE_KILL(pid_child, SIGKILL);
+ SAFE_WAITPID(pid_child, &status, 0);
+
+ SAFE_IOCTL(pidfd, PIDFD_GET_INFO, info);
+
+ TST_EXP_EQ_LI(info->mask & PIDFD_INFO_EXIT, PIDFD_INFO_EXIT);
+ TST_EXP_EQ_LI(WIFSIGNALED(info->exit_code), WIFSIGNALED(status));
+ TST_EXP_EQ_LI(WEXITSTATUS(info->exit_code), WEXITSTATUS(status));
+ TST_EXP_EQ_LI(WTERMSIG(info->exit_code), WTERMSIG(status));
+
+ TST_EXP_EXPR(WIFSIGNALED(info->exit_code) &&
+ WTERMSIG(info->exit_code) == SIGKILL);
+}
+
+static void setup(void)
+{
+ info->mask = PIDFD_INFO_EXIT;
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .forks_child = 1,
+ .needs_checkpoints = 1,
+ .min_kver = "6.15",
+ .bufs = (struct tst_buffers []) {
+ {&args, .size = sizeof(*args)},
+ {&info, .size = sizeof(*info)},
+ {}
+ }
+};
--
2.50.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [LTP] [PATCH 4/6] Add ioctl_pidfd02 test
2025-06-26 12:34 ` [LTP] [PATCH 4/6] Add ioctl_pidfd02 test Andrea Cervesato
@ 2025-06-27 9:11 ` Cyril Hrubis
2025-06-27 9:47 ` Cyril Hrubis
0 siblings, 1 reply; 16+ messages in thread
From: Cyril Hrubis @ 2025-06-27 9:11 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi!
> diff --git a/runtest/syscalls b/runtest/syscalls
> index 7f6312ce5fa241a778d8dda7f8ee9edd0a8800e6..23f335846663d62a39e6de3a8f6948c1b0acf8a5 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -613,6 +613,7 @@ ioctl_ficlonerange02 ioctl_ficlonerange02
> ioctl_fiemap01 ioctl_fiemap01
>
> ioctl_pidfd01 ioctl_pidfd01
> +ioctl_pidfd02 ioctl_pidfd02
>
> inotify_init1_01 inotify_init1_01
> inotify_init1_02 inotify_init1_02
> diff --git a/testcases/kernel/syscalls/ioctl/.gitignore b/testcases/kernel/syscalls/ioctl/.gitignore
> index aa952c1a7bae0ae2dbb04de0595f10d508b6759a..1c81c2bed8db952af0c93fb1ce5bfbad82794b60 100644
> --- a/testcases/kernel/syscalls/ioctl/.gitignore
> +++ b/testcases/kernel/syscalls/ioctl/.gitignore
> @@ -30,3 +30,4 @@
> /ioctl_ficlonerange02
> /ioctl_fiemap01
> /ioctl_pidfd01
> +/ioctl_pidfd02
> diff --git a/testcases/kernel/syscalls/ioctl/ioctl_pidfd02.c b/testcases/kernel/syscalls/ioctl/ioctl_pidfd02.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..82dd8c359938cdc7bf69cc2fd6afc90ce2a95290
> --- /dev/null
> +++ b/testcases/kernel/syscalls/ioctl/ioctl_pidfd02.c
> @@ -0,0 +1,62 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2025 Andrea Cervesato <andrea.cervesato@suse.com>
> + */
> +
> +/*\
> + * Check if the ioctl() function allows retrieval of a child's exit code
> + * using PIDFD_INFO_EXIT from a process that is isolated from the child.
> + */
> +
> +#include "tst_test.h"
> +#include "lapi/pidfd.h"
> +#include "lapi/sched.h"
> +
> +static struct tst_clone_args *args;
> +static struct pidfd_info *info;
> +
> +static void run(void)
> +{
> + int status;
> + int pidfd = 0;
> + pid_t pid_child;
> +
> + memset(args, 0, sizeof(struct tst_clone_args));
> +
> + args->flags = CLONE_PIDFD | CLONE_NEWUSER | CLONE_NEWPID;
> + args->pidfd = (uint64_t)&pidfd;
> + args->exit_signal = SIGCHLD;
> +
> + pid_child = SAFE_CLONE(args);
> + if (!pid_child) {
> + TST_CHECKPOINT_WAIT(0);
> + exit(100);
> + }
> +
> + /* child is not reaped, so ioctl() will pass */
> + info->mask = 0;
> + SAFE_IOCTL(pidfd, PIDFD_GET_INFO, info);
It will pass and:
- fill in some fields unconditionally
- if PIDFD_INFO_CREDS is set the info.*{uid,gid} should be checked
- if PIDFD_INFO_PID is set the info.*pid should be checked
- if PIDFD_INFO_CGROUPID is set the info.cgroupid will be also set
- the PIDFD_INFO_EXIT flag will not be set before the process did exit
> + TST_CHECKPOINT_WAKE(0);
> + SAFE_WAITPID(pid_child, &status, 0);
> +
> + /* child is now reaped, so we can ask for the exit status */
> + info->mask = PIDFD_INFO_EXIT;
> + SAFE_IOCTL(pidfd, PIDFD_GET_INFO, info);
> +
> + TST_EXP_EQ_LI(info->mask & PIDFD_INFO_EXIT, PIDFD_INFO_EXIT);
> + TST_EXP_EQ_LI(WIFEXITED(info->exit_code), WIFEXITED(status));
> + TST_EXP_EQ_LI(WEXITSTATUS(info->exit_code), WEXITSTATUS(status));
And here we should check that we got the same fields set as in the
previous case when the process was still running plus the exit_code.
I suppose that we will need two info structures so that we can do the
comparsion. Also it wouldn't harm to clear the structures with memset
before use.
> +}
> +
> +static struct tst_test test = {
> + .test_all = run,
> + .forks_child = 1,
> + .needs_checkpoints = 1,
> + .min_kver = "6.15",
> + .bufs = (struct tst_buffers []) {
> + {&args, .size = sizeof(*args)},
> + {&info, .size = sizeof(*info)},
> + {}
> + }
> +};
>
> --
> 2.50.0
>
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [LTP] [PATCH 4/6] Add ioctl_pidfd02 test
2025-06-27 9:11 ` Cyril Hrubis
@ 2025-06-27 9:47 ` Cyril Hrubis
2025-06-27 9:53 ` Cyril Hrubis
0 siblings, 1 reply; 16+ messages in thread
From: Cyril Hrubis @ 2025-06-27 9:47 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi!
> > + TST_EXP_EQ_LI(info->mask & PIDFD_INFO_EXIT, PIDFD_INFO_EXIT);
> > + TST_EXP_EQ_LI(WIFEXITED(info->exit_code), WIFEXITED(status));
> > + TST_EXP_EQ_LI(WEXITSTATUS(info->exit_code), WEXITSTATUS(status));
>
> And here we should check that we got the same fields set as in the
> previous case when the process was still running plus the exit_code.
>
> I suppose that we will need two info structures so that we can do the
> comparsion. Also it wouldn't harm to clear the structures with memset
> before use.
Ah no, if task has been reaped only exit value is available. So in the
latter case only the PIDFD_INFO_EXIT should be set in flags.
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [LTP] [PATCH 4/6] Add ioctl_pidfd02 test
2025-06-27 9:47 ` Cyril Hrubis
@ 2025-06-27 9:53 ` Cyril Hrubis
0 siblings, 0 replies; 16+ messages in thread
From: Cyril Hrubis @ 2025-06-27 9:53 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi!
> > > + TST_EXP_EQ_LI(info->mask & PIDFD_INFO_EXIT, PIDFD_INFO_EXIT);
> > > + TST_EXP_EQ_LI(WIFEXITED(info->exit_code), WIFEXITED(status));
> > > + TST_EXP_EQ_LI(WEXITSTATUS(info->exit_code), WEXITSTATUS(status));
> >
> > And here we should check that we got the same fields set as in the
> > previous case when the process was still running plus the exit_code.
> >
> > I suppose that we will need two info structures so that we can do the
> > comparsion. Also it wouldn't harm to clear the structures with memset
> > before use.
>
> Ah no, if task has been reaped only exit value is available. So in the
> latter case only the PIDFD_INFO_EXIT should be set in flags.
Uff and it's the same in both of the cases actually. Since the process
is cloned into new pid namespace, we can only get the return value.
So what we should check in the first case when the process is stil
running is that the PIDFD_INFO_EXIT flag is not set, since that
indicates that the exit_code has been filled in.
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [LTP] [PATCH 5/6] Add ioctl_pidfd03 test
2025-06-26 12:34 ` [LTP] [PATCH 5/6] Add ioctl_pidfd03 test Andrea Cervesato
@ 2025-06-27 9:56 ` Cyril Hrubis
2025-06-30 12:50 ` Andrea Cervesato via ltp
0 siblings, 1 reply; 16+ messages in thread
From: Cyril Hrubis @ 2025-06-27 9:56 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi!
> +static void run(void)
> +{
> + int status;
> + int pidfd = 0;
> + pid_t pid_child;
> +
> + memset(args, 0, sizeof(struct tst_clone_args));
> +
> + args->flags = CLONE_PIDFD | CLONE_NEWUSER | CLONE_NEWPID;
> + args->pidfd = (uint64_t)&pidfd;
> + args->exit_signal = SIGCHLD;
> +
> + pid_child = SAFE_CLONE(args);
> + if (!pid_child)
> + exit(100);
> +
> + SAFE_WAITPID(pid_child, &status, 0);
> +
> + TST_EXP_FAIL(ioctl(pidfd, PIDFD_GET_INFO, info), ESRCH);
> + TST_EXP_EQ_LI(info->mask & PIDFD_INFO_EXIT, 0);
If I'm reading the kernel code correctly, we should get the same result
even before the pid was waited for, so we may as well do this check
twice, once before the WAITPID() and once after the WAITPID().
> +}
> +
> +static struct tst_test test = {
> + .test_all = run,
> + .forks_child = 1,
> + .min_kver = "6.15",
> + .bufs = (struct tst_buffers []) {
> + {&args, .size = sizeof(*args)},
> + {&info, .size = sizeof(*info)},
> + {}
> + }
> +};
>
> --
> 2.50.0
>
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [LTP] [PATCH 0/6] ioctl_pidfd testing suite
2025-06-26 12:34 [LTP] [PATCH 0/6] ioctl_pidfd testing suite Andrea Cervesato
` (5 preceding siblings ...)
2025-06-26 12:34 ` [LTP] [PATCH 6/6] Add ioctl_pidfd04 test Andrea Cervesato
@ 2025-06-27 10:14 ` Cyril Hrubis
2025-07-01 11:15 ` Andrea Cervesato via ltp
6 siblings, 1 reply; 16+ messages in thread
From: Cyril Hrubis @ 2025-06-27 10:14 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi!
I guess that we miss a test for the case where the processes are in the
same pid namespace, e.g. process created by a plain old fork(). In that
case calling the ioctl() before the the process was waited for would
return the information I've mistakenly pointed out for the second test.
And we also do not have a tests for some error cases.
For instance a test that two processes in a different namespaces that
aren't in a parent-child relationship should fail with ESRCH regardless
the mask. I.e. if we clone two processes with CLONE_NEWPID they
shouldn't be able to retrieve exit value for each other.
And some minor checks, it looks like if we pass NULL arg (the info
structure pointer) we should get EINVAL. And we should be able to
trigger the case in kernel that checks usize < PIDFD_INFO_SIZE_VER0
with:
struct pidfd_info_invalid {
uint32_t dummy;
};
#define PIDFD_GET_INFO_SHORT _IOWR(PIDFS_IOCTL_MAGIC, 11, struct pidfd_info_invalid)
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [LTP] [PATCH 5/6] Add ioctl_pidfd03 test
2025-06-27 9:56 ` Cyril Hrubis
@ 2025-06-30 12:50 ` Andrea Cervesato via ltp
2025-06-30 14:30 ` Cyril Hrubis
0 siblings, 1 reply; 16+ messages in thread
From: Andrea Cervesato via ltp @ 2025-06-30 12:50 UTC (permalink / raw)
To: Cyril Hrubis, Andrea Cervesato; +Cc: ltp
Hi!
On 6/27/25 11:56 AM, Cyril Hrubis wrote:
> If I'm reading the kernel code correctly, we should get the same result
> even before the pid was waited for, so we may as well do this check
> twice, once before the WAITPID() and once after the WAITPID().
In this case, ESRCH is obtained only when info->mask == 0 __after__
child has been reaped.
If child has not completed, we obtain the same result of the
ioctl_pidfd02 check before waitpid().
- Andrea
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [LTP] [PATCH 5/6] Add ioctl_pidfd03 test
2025-06-30 12:50 ` Andrea Cervesato via ltp
@ 2025-06-30 14:30 ` Cyril Hrubis
0 siblings, 0 replies; 16+ messages in thread
From: Cyril Hrubis @ 2025-06-30 14:30 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi!
> > If I'm reading the kernel code correctly, we should get the same result
> > even before the pid was waited for, so we may as well do this check
> > twice, once before the WAITPID() and once after the WAITPID().
> In this case, ESRCH is obtained only when info->mask == 0 __after__
> child has been reaped.
> If child has not completed, we obtain the same result of the
> ioctl_pidfd02 check before waitpid().
Sigh, right, I misread the kernel code again.
We get ESRCH in the case of:
- the target pid is not in our namespace or child namespace
- task was reaped and PIDFD_INFO_EXIT was not set
- task was reaped before we called get_task_cred()
- task was reaped after we filled in data from task_cred
(there is another check at the end of the function to make sure we do
not return stale data)
So I suppose that we can hit the first two, the second two are
inherently racy.
So after all with a pidfd pointing to a process in a child pid namespace
we get all the uids/gids and pid filled in. Possibly changed by
mappings, but I suppose these are going to be 1:1 since we haven't set
any mapping tables.
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [LTP] [PATCH 0/6] ioctl_pidfd testing suite
2025-06-27 10:14 ` [LTP] [PATCH 0/6] ioctl_pidfd testing suite Cyril Hrubis
@ 2025-07-01 11:15 ` Andrea Cervesato via ltp
2025-07-01 11:40 ` Cyril Hrubis
0 siblings, 1 reply; 16+ messages in thread
From: Andrea Cervesato via ltp @ 2025-07-01 11:15 UTC (permalink / raw)
To: Cyril Hrubis, Andrea Cervesato; +Cc: ltp
On 6/27/25 12:14 PM, Cyril Hrubis wrote:
> I guess that we miss a test for the case where the processes are in the
> same pid namespace, e.g. process created by a plain old fork(). In that
> case calling the ioctl() before the the process was waited for would
> return the information I've mistakenly pointed out for the second test.
Sorry but I don't get this one. When we fork() a process and we check
its exit code via ioctl(PIDFD_GET_INFO) __before__ the child has been
reaped, we only need to check if mask is still having PIDFD_INFO_EXIT,
because that's not available.The same for exit_code.
Am I missing something?
- Andrea
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [LTP] [PATCH 0/6] ioctl_pidfd testing suite
2025-07-01 11:15 ` Andrea Cervesato via ltp
@ 2025-07-01 11:40 ` Cyril Hrubis
0 siblings, 0 replies; 16+ messages in thread
From: Cyril Hrubis @ 2025-07-01 11:40 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi!
> > I guess that we miss a test for the case where the processes are in the
> > same pid namespace, e.g. process created by a plain old fork(). In that
> > case calling the ioctl() before the the process was waited for would
> > return the information I've mistakenly pointed out for the second test.
>
> Sorry but I don't get this one. When we fork() a process and we check
> its exit code via ioctl(PIDFD_GET_INFO) __before__ the child has been
> reaped, we only need to check if mask is still having PIDFD_INFO_EXIT,
> because that's not available.The same for exit_code.
>
> Am I missing something?
That paragraph was still written under the assumption that you are not
supposed to get anything else than exit vaule from a process that is in
a different namespace.
The main point should have been that all the tests you have sumbitted
are written so that the child process is cloned into a new pid
namespace. We need at least one test where both the child and the parent
are in the same namespace. Either cloned without pid namespace or
created by plain old fork().
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2025-07-01 11:40 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-26 12:34 [LTP] [PATCH 0/6] ioctl_pidfd testing suite Andrea Cervesato
2025-06-26 12:34 ` [LTP] [PATCH 1/6] Provide pidfd parameter in tst_clone_args Andrea Cervesato
2025-06-26 12:34 ` [LTP] [PATCH 2/6] Fallback PIDFD_GET_INFO related definitions Andrea Cervesato
2025-06-26 12:34 ` [LTP] [PATCH 3/6] Add ioctl_pidfd01 test Andrea Cervesato
2025-06-26 12:34 ` [LTP] [PATCH 4/6] Add ioctl_pidfd02 test Andrea Cervesato
2025-06-27 9:11 ` Cyril Hrubis
2025-06-27 9:47 ` Cyril Hrubis
2025-06-27 9:53 ` Cyril Hrubis
2025-06-26 12:34 ` [LTP] [PATCH 5/6] Add ioctl_pidfd03 test Andrea Cervesato
2025-06-27 9:56 ` Cyril Hrubis
2025-06-30 12:50 ` Andrea Cervesato via ltp
2025-06-30 14:30 ` Cyril Hrubis
2025-06-26 12:34 ` [LTP] [PATCH 6/6] Add ioctl_pidfd04 test Andrea Cervesato
2025-06-27 10:14 ` [LTP] [PATCH 0/6] ioctl_pidfd testing suite Cyril Hrubis
2025-07-01 11:15 ` Andrea Cervesato via ltp
2025-07-01 11:40 ` Cyril Hrubis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox