Skip to content

Commit cbb8425

Browse files
committed
selftests/coredump: add second PIDFD_INFO_COREDUMP_SIGNAL test
Verify that when using simple socket-based coredump (@ pattern), the coredump_signal field is correctly exposed as SIGABRT. Link: https://patch.msgid.link/20251028-work-coredump-signal-v1-22-ca449b7b7aa0@kernel.org Reviewed-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 619e222 commit cbb8425

1 file changed

Lines changed: 146 additions & 0 deletions

File tree

tools/testing/selftests/coredump/coredump_socket_test.c

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,152 @@ TEST_F(coredump, socket_coredump_signal_sigsegv)
576576
wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
577577
}
578578

579+
/*
580+
* Test: PIDFD_INFO_COREDUMP_SIGNAL via simple socket coredump with SIGABRT
581+
*
582+
* Verify that when using simple socket-based coredump (@ pattern),
583+
* the coredump_signal field is correctly exposed as SIGABRT.
584+
*/
585+
TEST_F(coredump, socket_coredump_signal_sigabrt)
586+
{
587+
int pidfd, ret, status;
588+
pid_t pid, pid_coredump_server;
589+
struct pidfd_info info = {};
590+
int ipc_sockets[2];
591+
char c;
592+
593+
ASSERT_TRUE(set_core_pattern("@/tmp/coredump.socket"));
594+
595+
ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
596+
ASSERT_EQ(ret, 0);
597+
598+
pid_coredump_server = fork();
599+
ASSERT_GE(pid_coredump_server, 0);
600+
if (pid_coredump_server == 0) {
601+
int fd_server = -1, fd_coredump = -1, fd_peer_pidfd = -1, fd_core_file = -1;
602+
int exit_code = EXIT_FAILURE;
603+
604+
close(ipc_sockets[0]);
605+
606+
fd_server = create_and_listen_unix_socket("/tmp/coredump.socket");
607+
if (fd_server < 0) {
608+
fprintf(stderr, "socket_coredump_signal_sigabrt: create_and_listen_unix_socket failed: %m\n");
609+
goto out;
610+
}
611+
612+
if (write_nointr(ipc_sockets[1], "1", 1) < 0) {
613+
fprintf(stderr, "socket_coredump_signal_sigabrt: write_nointr to ipc socket failed: %m\n");
614+
goto out;
615+
}
616+
617+
close(ipc_sockets[1]);
618+
619+
fd_coredump = accept4(fd_server, NULL, NULL, SOCK_CLOEXEC);
620+
if (fd_coredump < 0) {
621+
fprintf(stderr, "socket_coredump_signal_sigabrt: accept4 failed: %m\n");
622+
goto out;
623+
}
624+
625+
fd_peer_pidfd = get_peer_pidfd(fd_coredump);
626+
if (fd_peer_pidfd < 0) {
627+
fprintf(stderr, "socket_coredump_signal_sigabrt: get_peer_pidfd failed\n");
628+
goto out;
629+
}
630+
631+
if (!get_pidfd_info(fd_peer_pidfd, &info)) {
632+
fprintf(stderr, "socket_coredump_signal_sigabrt: get_pidfd_info failed\n");
633+
goto out;
634+
}
635+
636+
if (!(info.mask & PIDFD_INFO_COREDUMP)) {
637+
fprintf(stderr, "socket_coredump_signal_sigabrt: PIDFD_INFO_COREDUMP not set in mask\n");
638+
goto out;
639+
}
640+
641+
if (!(info.coredump_mask & PIDFD_COREDUMPED)) {
642+
fprintf(stderr, "socket_coredump_signal_sigabrt: PIDFD_COREDUMPED not set in coredump_mask\n");
643+
goto out;
644+
}
645+
646+
/* Verify coredump_signal is available and correct */
647+
if (!(info.mask & PIDFD_INFO_COREDUMP_SIGNAL)) {
648+
fprintf(stderr, "socket_coredump_signal_sigabrt: PIDFD_INFO_COREDUMP_SIGNAL not set in mask\n");
649+
goto out;
650+
}
651+
652+
if (info.coredump_signal != SIGABRT) {
653+
fprintf(stderr, "socket_coredump_signal_sigabrt: coredump_signal=%d, expected SIGABRT=%d\n",
654+
info.coredump_signal, SIGABRT);
655+
goto out;
656+
}
657+
658+
fd_core_file = open_coredump_tmpfile(self->fd_tmpfs_detached);
659+
if (fd_core_file < 0) {
660+
fprintf(stderr, "socket_coredump_signal_sigabrt: open_coredump_tmpfile failed: %m\n");
661+
goto out;
662+
}
663+
664+
for (;;) {
665+
char buffer[4096];
666+
ssize_t bytes_read, bytes_write;
667+
668+
bytes_read = read(fd_coredump, buffer, sizeof(buffer));
669+
if (bytes_read < 0) {
670+
fprintf(stderr, "socket_coredump_signal_sigabrt: read from coredump socket failed: %m\n");
671+
goto out;
672+
}
673+
674+
if (bytes_read == 0)
675+
break;
676+
677+
bytes_write = write(fd_core_file, buffer, bytes_read);
678+
if (bytes_read != bytes_write) {
679+
fprintf(stderr, "socket_coredump_signal_sigabrt: write to core file failed (read=%zd, write=%zd): %m\n",
680+
bytes_read, bytes_write);
681+
goto out;
682+
}
683+
}
684+
685+
exit_code = EXIT_SUCCESS;
686+
fprintf(stderr, "socket_coredump_signal_sigabrt: completed successfully\n");
687+
out:
688+
if (fd_core_file >= 0)
689+
close(fd_core_file);
690+
if (fd_peer_pidfd >= 0)
691+
close(fd_peer_pidfd);
692+
if (fd_coredump >= 0)
693+
close(fd_coredump);
694+
if (fd_server >= 0)
695+
close(fd_server);
696+
_exit(exit_code);
697+
}
698+
self->pid_coredump_server = pid_coredump_server;
699+
700+
EXPECT_EQ(close(ipc_sockets[1]), 0);
701+
ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
702+
EXPECT_EQ(close(ipc_sockets[0]), 0);
703+
704+
pid = fork();
705+
ASSERT_GE(pid, 0);
706+
if (pid == 0)
707+
abort();
708+
709+
pidfd = sys_pidfd_open(pid, 0);
710+
ASSERT_GE(pidfd, 0);
711+
712+
waitpid(pid, &status, 0);
713+
ASSERT_TRUE(WIFSIGNALED(status));
714+
ASSERT_EQ(WTERMSIG(status), SIGABRT);
715+
ASSERT_TRUE(WCOREDUMP(status));
716+
717+
ASSERT_TRUE(get_pidfd_info(pidfd, &info));
718+
ASSERT_TRUE(!!(info.mask & PIDFD_INFO_COREDUMP));
719+
ASSERT_TRUE(!!(info.mask & PIDFD_INFO_COREDUMP_SIGNAL));
720+
ASSERT_EQ(info.coredump_signal, SIGABRT);
721+
722+
wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
723+
}
724+
579725
TEST_F(coredump, socket_invalid_paths)
580726
{
581727
ASSERT_FALSE(set_core_pattern("@ /tmp/coredump.socket"));

0 commit comments

Comments
 (0)