From: Nickolai Zeldovich <nickolai@csail.mit.edu>
To: Christian Brauner <brauner@kernel.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>, Jan Kara <jack@suse.cz>,
Shuah Khan <shuah@kernel.org>, Jann Horn <jannh@google.com>,
Alexander Mikhalitsyn <alexander@mihalicyn.com>,
Luca Boccassi <luca.boccassi@gmail.com>,
linux-fsdevel@vger.kernel.org, linux-kselftest@vger.kernel.org,
linux-kernel@vger.kernel.org,
Nickolai Zeldovich <nickolai@csail.mit.edu>
Subject: [PATCH v2 2/2] selftests/pidfd: test that fields beyond the struct size are not reported
Date: Sat, 24 Oct 2026 00:13:34 -0400 [thread overview]
Message-ID: <20261024041334.831273-3-nickolai@csail.mit.edu> (raw)
In-Reply-To: <20261024041334.831273-1-nickolai@csail.mit.edu>
PIDFD_GET_INFO must not set the mask bit of a field that lies beyond
the struct size encoded in the ioctl command. Add a test that requests
the coredump fields and the supported mask with PIDFD_INFO_SIZE_VER0
over a full-size, poisoned struct, and checks that the mask names none
of those fields and that the poison behind the first 64 bytes is
intact.
Add fallback definitions of PIDFD_INFO_SIZE_VER0 to VER3 to pidfd.h,
like the other uapi constants there.
Signed-off-by: Nickolai Zeldovich <nickolai@csail.mit.edu>
---
Notes:
Result in a QEMU x86_64 guest on mainline 17bb0e2f6c80, without
patch 1:
# pidfd_info_test.c:801:info_size_ver0_mask:Expected 0 (0) == !!(info.mask & (PIDFD_INFO_COREDUMP | ...)) (1)
not ok 3 global.info_size_ver0_mask
With patch 1:
ok 3 global.info_size_ver0_mask
tools/testing/selftests/pidfd/pidfd.h | 16 +++++++
.../testing/selftests/pidfd/pidfd_info_test.c | 48 +++++++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/tools/testing/selftests/pidfd/pidfd.h b/tools/testing/selftests/pidfd/pidfd.h
index 5a4e78c10f434..cf146d3273348 100644
--- a/tools/testing/selftests/pidfd/pidfd.h
+++ b/tools/testing/selftests/pidfd/pidfd.h
@@ -160,6 +160,22 @@
#define PIDFD_INFO_COREDUMP_CODE (1UL << 7)
#endif
+#ifndef PIDFD_INFO_SIZE_VER0
+#define PIDFD_INFO_SIZE_VER0 64 /* sizeof first published struct */
+#endif
+
+#ifndef PIDFD_INFO_SIZE_VER1
+#define PIDFD_INFO_SIZE_VER1 72 /* sizeof second published struct */
+#endif
+
+#ifndef PIDFD_INFO_SIZE_VER2
+#define PIDFD_INFO_SIZE_VER2 80 /* sizeof third published struct */
+#endif
+
+#ifndef PIDFD_INFO_SIZE_VER3
+#define PIDFD_INFO_SIZE_VER3 88 /* sizeof fourth published struct */
+#endif
+
#ifndef PIDFD_COREDUMPED
#define PIDFD_COREDUMPED (1U << 0) /* Did crash and... */
#endif
diff --git a/tools/testing/selftests/pidfd/pidfd_info_test.c b/tools/testing/selftests/pidfd/pidfd_info_test.c
index 597012ed195f0..ee08df3dc3d2b 100644
--- a/tools/testing/selftests/pidfd/pidfd_info_test.c
+++ b/tools/testing/selftests/pidfd/pidfd_info_test.c
@@ -764,4 +764,52 @@ TEST(supported_mask_with_other_fields)
close(pidfd);
}
+/*
+ * Test: fields beyond the caller's struct size are not reported
+ *
+ * Request the coredump and supported_mask fields with a struct of the
+ * first published size. None of those fields fit, so the returned mask
+ * must not name them and the memory behind the struct must be untouched.
+ */
+TEST(info_size_ver0_mask)
+{
+ struct pidfd_info info = {
+ .mask = PIDFD_INFO_COREDUMP | PIDFD_INFO_SUPPORTED_MASK,
+ .coredump_mask = 0xdeadbeef,
+ .coredump_signal = 0xdeadbeef,
+ .coredump_code = 0xdeadbeef,
+ .supported_mask = 0xdeadbeefdeadbeefULL,
+ };
+ unsigned int cmd = _IOC(_IOC_READ | _IOC_WRITE, PIDFS_IOCTL_MAGIC, 11,
+ PIDFD_INFO_SIZE_VER0);
+ int pidfd;
+ pid_t pid;
+
+ pid = create_child(&pidfd, 0);
+ ASSERT_GE(pid, 0);
+
+ if (pid == 0)
+ pause();
+
+ ASSERT_EQ(ioctl(pidfd, cmd, &info), 0);
+
+ /* The fields that fit are reported as usual. */
+ ASSERT_TRUE(!!(info.mask & PIDFD_INFO_PID));
+ ASSERT_TRUE(!!(info.mask & PIDFD_INFO_CREDS));
+
+ /* The fields that do not fit are neither reported nor written. */
+ ASSERT_FALSE(!!(info.mask & (PIDFD_INFO_COREDUMP |
+ PIDFD_INFO_COREDUMP_SIGNAL |
+ PIDFD_INFO_COREDUMP_CODE |
+ PIDFD_INFO_SUPPORTED_MASK)));
+ ASSERT_EQ(info.coredump_mask, 0xdeadbeef);
+ ASSERT_EQ(info.coredump_signal, 0xdeadbeef);
+ ASSERT_EQ(info.coredump_code, 0xdeadbeef);
+ ASSERT_EQ(info.supported_mask, 0xdeadbeefdeadbeefULL);
+
+ sys_pidfd_send_signal(pidfd, SIGKILL, NULL, 0);
+ sys_waitid(P_PIDFD, pidfd, NULL, WEXITED);
+ close(pidfd);
+}
+
TEST_HARNESS_MAIN
--
2.53.0
prev parent reply other threads:[~2026-10-24 4:13 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-17 2:06 [PATCH v1] pidfs: do not report fields that do not fit into the caller's struct Nickolai Zeldovich
2026-10-21 10:42 ` Christian Brauner
2026-10-24 4:13 ` [PATCH v2 0/2] " Nickolai Zeldovich
2026-10-24 4:13 ` [PATCH v2 1/2] " Nickolai Zeldovich
2026-10-24 9:06 ` Luca Boccassi
2026-10-24 4:13 ` Nickolai Zeldovich [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261024041334.831273-3-nickolai@csail.mit.edu \
--to=nickolai@csail.mit.edu \
--cc=alexander@mihalicyn.com \
--cc=brauner@kernel.org \
--cc=jack@suse.cz \
--cc=jannh@google.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=luca.boccassi@gmail.com \
--cc=shuah@kernel.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®