@@ -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+
579725TEST_F (coredump , socket_invalid_paths )
580726{
581727 ASSERT_FALSE (set_core_pattern ("@ /tmp/coredump.socket" ));
0 commit comments