]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
selftests: check pidfd_info->coredump_code correctness
authorEmanuele Rocca <emanuele.rocca@arm.com>
Mon, 23 Mar 2026 13:03:15 +0000 (14:03 +0100)
committerChristian Brauner <brauner@kernel.org>
Mon, 23 Mar 2026 15:29:15 +0000 (16:29 +0100)
Extend the coredump_socket and coredump_socket_protocol selftests to verify
that the field coredump_code is set as expected in struct pidfd_info.

Signed-off-by: Emanuele Rocca <emanuele.rocca@arm.com>
Link: https://patch.msgid.link/acE6Eyuv2MM75pmk@NH27D9T0LF
Signed-off-by: Christian Brauner <brauner@kernel.org>
tools/testing/selftests/coredump/coredump_socket_protocol_test.c
tools/testing/selftests/coredump/coredump_socket_test.c
tools/testing/selftests/coredump/coredump_test_helpers.c
tools/testing/selftests/pidfd/pidfd.h
tools/testing/selftests/pidfd/pidfd_info_test.c

index d19b6717c53ef100608b6c9ac24eebb9f812b2bf..d9fa6239b5a9fdcebd35e73c80ceaeb22566759a 100644 (file)
@@ -1004,6 +1004,8 @@ out:
  *
  * Verify that when using socket-based coredump protocol,
  * the coredump_signal field is correctly exposed as SIGSEGV.
+ * Also check that the coredump_code field is correctly exposed
+ * as SEGV_MAPERR.
  */
 TEST_F(coredump, socket_coredump_signal_sigsegv)
 {
@@ -1079,6 +1081,18 @@ TEST_F(coredump, socket_coredump_signal_sigsegv)
                        goto out;
                }
 
+               /* Verify coredump_code is available and correct */
+               if (!(info.mask & PIDFD_INFO_COREDUMP_CODE)) {
+                       fprintf(stderr, "socket_coredump_signal_sigsegv: PIDFD_INFO_COREDUMP_CODE not set in mask\n");
+                       goto out;
+               }
+
+               if (info.coredump_code != SEGV_MAPERR) {
+                       fprintf(stderr, "socket_coredump_signal_sigsegv: coredump_code=%d, expected SEGV_MAPERR=%d\n",
+                               info.coredump_code, SEGV_MAPERR);
+                       goto out;
+               }
+
                if (!read_coredump_req(fd_coredump, &req)) {
                        fprintf(stderr, "socket_coredump_signal_sigsegv: read_coredump_req failed\n");
                        goto out;
@@ -1128,6 +1142,8 @@ out:
        ASSERT_TRUE(!!(info.mask & PIDFD_INFO_COREDUMP));
        ASSERT_TRUE(!!(info.mask & PIDFD_INFO_COREDUMP_SIGNAL));
        ASSERT_EQ(info.coredump_signal, SIGSEGV);
+       ASSERT_TRUE(!!(info.mask & PIDFD_INFO_COREDUMP_CODE));
+       ASSERT_EQ(info.coredump_code, SEGV_MAPERR);
 
        wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
 }
@@ -1137,6 +1153,8 @@ out:
  *
  * Verify that when using socket-based coredump protocol,
  * the coredump_signal field is correctly exposed as SIGABRT.
+ * Also check that the coredump_code field is correctly exposed
+ * as SI_TKILL.
  */
 TEST_F(coredump, socket_coredump_signal_sigabrt)
 {
@@ -1212,6 +1230,12 @@ TEST_F(coredump, socket_coredump_signal_sigabrt)
                        goto out;
                }
 
+               if (info.coredump_code != SI_TKILL) {
+                       fprintf(stderr, "socket_coredump_signal_sigabrt: coredump_code=%d, expected SI_TKILL=%d\n",
+                               info.coredump_code, SI_TKILL);
+                       goto out;
+               }
+
                if (!read_coredump_req(fd_coredump, &req)) {
                        fprintf(stderr, "socket_coredump_signal_sigabrt: read_coredump_req failed\n");
                        goto out;
@@ -1261,6 +1285,8 @@ out:
        ASSERT_TRUE(!!(info.mask & PIDFD_INFO_COREDUMP));
        ASSERT_TRUE(!!(info.mask & PIDFD_INFO_COREDUMP_SIGNAL));
        ASSERT_EQ(info.coredump_signal, SIGABRT);
+       ASSERT_TRUE(!!(info.mask & PIDFD_INFO_COREDUMP_CODE));
+       ASSERT_EQ(info.coredump_code, SI_TKILL);
 
        wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
 }
index 7e26d4a6a15db7c8391f0f3228f9148231be26f8..422728f632ca6c22d2b2ec5c1413177b0991906a 100644 (file)
@@ -435,6 +435,8 @@ out:
  *
  * Verify that when using simple socket-based coredump (@ pattern),
  * the coredump_signal field is correctly exposed as SIGSEGV.
+ * Also check that the coredump_code field is correctly exposed
+ * as SEGV_MAPERR.
  */
 TEST_F(coredump, socket_coredump_signal_sigsegv)
 {
@@ -509,6 +511,18 @@ TEST_F(coredump, socket_coredump_signal_sigsegv)
                        goto out;
                }
 
+               /* Verify coredump_code is available and correct */
+               if (!(info.mask & PIDFD_INFO_COREDUMP_CODE)) {
+                       fprintf(stderr, "socket_coredump_signal_sigsegv: PIDFD_INFO_COREDUMP_CODE not set in mask\n");
+                       goto out;
+               }
+
+               if (info.coredump_code != SEGV_MAPERR) {
+                       fprintf(stderr, "socket_coredump_signal_sigsegv: coredump_code=%d, expected SEGV_MAPERR=%d\n",
+                               info.coredump_code, SEGV_MAPERR);
+                       goto out;
+               }
+
                fd_core_file = open_coredump_tmpfile(self->fd_tmpfs_detached);
                if (fd_core_file < 0) {
                        fprintf(stderr, "socket_coredump_signal_sigsegv: open_coredump_tmpfile failed: %m\n");
@@ -572,6 +586,8 @@ out:
        ASSERT_TRUE(!!(info.mask & PIDFD_INFO_COREDUMP));
        ASSERT_TRUE(!!(info.mask & PIDFD_INFO_COREDUMP_SIGNAL));
        ASSERT_EQ(info.coredump_signal, SIGSEGV);
+       ASSERT_TRUE(!!(info.mask & PIDFD_INFO_COREDUMP_CODE));
+       ASSERT_EQ(info.coredump_code, SEGV_MAPERR);
 
        wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
 }
@@ -581,6 +597,8 @@ out:
  *
  * Verify that when using simple socket-based coredump (@ pattern),
  * the coredump_signal field is correctly exposed as SIGABRT.
+ * Also check that the coredump_code field is correctly exposed
+ * as SI_TKILL.
  */
 TEST_F(coredump, socket_coredump_signal_sigabrt)
 {
@@ -655,6 +673,18 @@ TEST_F(coredump, socket_coredump_signal_sigabrt)
                        goto out;
                }
 
+               /* Verify coredump_code is available and correct */
+               if (!(info.mask & PIDFD_INFO_COREDUMP_CODE)) {
+                       fprintf(stderr, "socket_coredump_signal_sigabrt: PIDFD_INFO_COREDUMP_CODE not set in mask\n");
+                       goto out;
+               }
+
+               if (info.coredump_code != SI_TKILL) {
+                       fprintf(stderr, "socket_coredump_signal_sigabrt: coredump_code=%d, expected SI_TKILL=%d\n",
+                               info.coredump_code, SI_TKILL);
+                       goto out;
+               }
+
                fd_core_file = open_coredump_tmpfile(self->fd_tmpfs_detached);
                if (fd_core_file < 0) {
                        fprintf(stderr, "socket_coredump_signal_sigabrt: open_coredump_tmpfile failed: %m\n");
@@ -718,6 +748,8 @@ out:
        ASSERT_TRUE(!!(info.mask & PIDFD_INFO_COREDUMP));
        ASSERT_TRUE(!!(info.mask & PIDFD_INFO_COREDUMP_SIGNAL));
        ASSERT_EQ(info.coredump_signal, SIGABRT);
+       ASSERT_TRUE(!!(info.mask & PIDFD_INFO_COREDUMP_CODE));
+       ASSERT_EQ(info.coredump_code, SI_TKILL);
 
        wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
 }
index 2c850e0b1b57c3561664dfebf8a064b58f8fe6da..2a20faf9cb0ad30fe04dce58d8e61b0588e15064 100644 (file)
@@ -148,8 +148,8 @@ bool get_pidfd_info(int fd_peer_pidfd, struct pidfd_info *info)
                fprintf(stderr, "get_pidfd_info: ioctl(PIDFD_GET_INFO) failed: %m\n");
                return false;
        }
-       fprintf(stderr, "get_pidfd_info: mask=0x%llx, coredump_mask=0x%x, coredump_signal=%d\n",
-               (unsigned long long)info->mask, info->coredump_mask, info->coredump_signal);
+       fprintf(stderr, "get_pidfd_info: mask=0x%llx, coredump_mask=0x%x, coredump_signal=%d, coredump_code=%d\n",
+               (unsigned long long)info->mask, info->coredump_mask, info->coredump_signal, info->coredump_code);
        return true;
 }
 
index 9085c1a3c005e9a0fcd89194d123dc9e22a79681..5a4e78c10f434e13fc22b98a261919421dae82f9 100644 (file)
 #define PIDFD_INFO_COREDUMP_SIGNAL     (1UL << 6)
 #endif
 
+#ifndef PIDFD_INFO_COREDUMP_CODE
+#define PIDFD_INFO_COREDUMP_CODE       (1UL << 7)
+#endif
+
 #ifndef PIDFD_COREDUMPED
 #define PIDFD_COREDUMPED       (1U << 0) /* Did crash and... */
 #endif
@@ -194,6 +198,7 @@ struct pidfd_info {
        struct {
                __u32 coredump_mask;
                __u32 coredump_signal;
+               __u32 coredump_code;
        };
        __u64 supported_mask;
 };
index 8bed951e06a0f0c4ba533830e482abc9e04a2d6e..597012ed195f0fdc02993a4b9c60b963c86bc73d 100644 (file)
@@ -724,6 +724,7 @@ TEST(supported_mask_field)
        ASSERT_TRUE(!!(info.supported_mask & PIDFD_INFO_COREDUMP));
        ASSERT_TRUE(!!(info.supported_mask & PIDFD_INFO_SUPPORTED_MASK));
        ASSERT_TRUE(!!(info.supported_mask & PIDFD_INFO_COREDUMP_SIGNAL));
+       ASSERT_TRUE(!!(info.supported_mask & PIDFD_INFO_COREDUMP_CODE));
 
        /* Clean up */
        sys_pidfd_send_signal(pidfd, SIGKILL, NULL, 0);