@@ -646,6 +646,77 @@ static int umh_coredump_setup(struct subprocess_info *info, struct cred *new)
646646}
647647
648648#ifdef CONFIG_UNIX
649+ static bool coredump_sock_connect (struct core_name * cn , struct coredump_params * cprm )
650+ {
651+ struct file * file __free (fput ) = NULL ;
652+ struct sockaddr_un addr = {
653+ .sun_family = AF_UNIX ,
654+ };
655+ ssize_t addr_len ;
656+ int retval ;
657+ struct socket * socket ;
658+
659+ addr_len = strscpy (addr .sun_path , cn -> corename );
660+ if (addr_len < 0 )
661+ return false;
662+ addr_len += offsetof(struct sockaddr_un , sun_path ) + 1 ;
663+
664+ /*
665+ * It is possible that the userspace process which is supposed
666+ * to handle the coredump and is listening on the AF_UNIX socket
667+ * coredumps. Userspace should just mark itself non dumpable.
668+ */
669+
670+ retval = sock_create_kern (& init_net , AF_UNIX , SOCK_STREAM , 0 , & socket );
671+ if (retval < 0 )
672+ return false;
673+
674+ file = sock_alloc_file (socket , 0 , NULL );
675+ if (IS_ERR (file ))
676+ return false;
677+
678+ /*
679+ * Set the thread-group leader pid which is used for the peer
680+ * credentials during connect() below. Then immediately register
681+ * it in pidfs...
682+ */
683+ cprm -> pid = task_tgid (current );
684+ retval = pidfs_register_pid (cprm -> pid );
685+ if (retval )
686+ return false;
687+
688+ /*
689+ * ... and set the coredump information so userspace has it
690+ * available after connect()...
691+ */
692+ pidfs_coredump (cprm );
693+
694+ retval = kernel_connect (socket , (struct sockaddr * )(& addr ), addr_len ,
695+ O_NONBLOCK | SOCK_COREDUMP );
696+ /*
697+ * ... Make sure to only put our reference after connect() took
698+ * its own reference keeping the pidfs entry alive ...
699+ */
700+ pidfs_put_pid (cprm -> pid );
701+
702+ if (retval ) {
703+ if (retval == - EAGAIN )
704+ coredump_report_failure ("Coredump socket %s receive queue full" , addr .sun_path );
705+ else
706+ coredump_report_failure ("Coredump socket connection %s failed %d" , addr .sun_path , retval );
707+ return false;
708+ }
709+
710+ /* ... and validate that @sk_peer_pid matches @cprm.pid. */
711+ if (WARN_ON_ONCE (unix_peer (socket -> sk )-> sk_peer_pid != cprm -> pid ))
712+ return false;
713+
714+ cprm -> limit = RLIM_INFINITY ;
715+ cprm -> file = no_free_ptr (file );
716+
717+ return true;
718+ }
719+
649720static inline bool coredump_sock_recv (struct file * file , struct coredump_ack * ack , size_t size , int flags )
650721{
651722 struct msghdr msg = {};
@@ -707,7 +778,7 @@ static inline void coredump_sock_shutdown(struct file *file)
707778 kernel_sock_shutdown (socket , SHUT_WR );
708779}
709780
710- static bool coredump_request (struct core_name * cn , struct coredump_params * cprm )
781+ static bool coredump_sock_request (struct core_name * cn , struct coredump_params * cprm )
711782{
712783 struct coredump_req req = {
713784 .size = sizeof (struct coredump_req ),
@@ -770,6 +841,14 @@ static bool coredump_request(struct core_name *cn, struct coredump_params *cprm)
770841 return coredump_sock_mark (cprm -> file , COREDUMP_MARK_REQACK );
771842}
772843#else
844+ static bool coredump_sock_connect (struct core_name * cn ,
845+ struct coredump_params * cprm )
846+ {
847+ coredump_report_failure ("Core dump socket support %s disabled" , cn -> corename );
848+ return false;
849+ }
850+ static bool coredump_sock_request (struct core_name * cn ,
851+ struct coredump_params * cprm ) { return false; }
773852static inline void coredump_sock_wait (struct file * file ) { }
774853static inline void coredump_sock_shutdown (struct file * file ) { }
775854#endif
@@ -994,83 +1073,13 @@ void do_coredump(const kernel_siginfo_t *siginfo)
9941073 }
9951074 case COREDUMP_SOCK_REQ :
9961075 fallthrough ;
997- case COREDUMP_SOCK : {
998- #ifdef CONFIG_UNIX
999- struct file * file __free (fput ) = NULL ;
1000- struct sockaddr_un addr = {
1001- .sun_family = AF_UNIX ,
1002- };
1003- ssize_t addr_len ;
1004- struct socket * socket ;
1005-
1006- addr_len = strscpy (addr .sun_path , cn .corename );
1007- if (addr_len < 0 )
1008- goto close_fail ;
1009- addr_len += offsetof(struct sockaddr_un , sun_path ) + 1 ;
1010-
1011- /*
1012- * It is possible that the userspace process which is
1013- * supposed to handle the coredump and is listening on
1014- * the AF_UNIX socket coredumps. Userspace should just
1015- * mark itself non dumpable.
1016- */
1017-
1018- retval = sock_create_kern (& init_net , AF_UNIX , SOCK_STREAM , 0 , & socket );
1019- if (retval < 0 )
1020- goto close_fail ;
1021-
1022- file = sock_alloc_file (socket , 0 , NULL );
1023- if (IS_ERR (file ))
1024- goto close_fail ;
1025-
1026- /*
1027- * Set the thread-group leader pid which is used for the
1028- * peer credentials during connect() below. Then
1029- * immediately register it in pidfs...
1030- */
1031- cprm .pid = task_tgid (current );
1032- retval = pidfs_register_pid (cprm .pid );
1033- if (retval )
1034- goto close_fail ;
1035-
1036- /*
1037- * ... and set the coredump information so userspace
1038- * has it available after connect()...
1039- */
1040- pidfs_coredump (& cprm );
1041-
1042- retval = kernel_connect (socket , (struct sockaddr * )(& addr ),
1043- addr_len , O_NONBLOCK | SOCK_COREDUMP );
1044-
1045- /*
1046- * ... Make sure to only put our reference after connect() took
1047- * its own reference keeping the pidfs entry alive ...
1048- */
1049- pidfs_put_pid (cprm .pid );
1050-
1051- if (retval ) {
1052- if (retval == - EAGAIN )
1053- coredump_report_failure ("Coredump socket %s receive queue full" , addr .sun_path );
1054- else
1055- coredump_report_failure ("Coredump socket connection %s failed %d" , addr .sun_path , retval );
1076+ case COREDUMP_SOCK :
1077+ if (!coredump_sock_connect (& cn , & cprm ))
10561078 goto close_fail ;
1057- }
10581079
1059- /* ... and validate that @sk_peer_pid matches @cprm.pid. */
1060- if (WARN_ON_ONCE (unix_peer (socket -> sk )-> sk_peer_pid != cprm .pid ))
1080+ if (!coredump_sock_request (& cn , & cprm ))
10611081 goto close_fail ;
1062-
1063- cprm .limit = RLIM_INFINITY ;
1064- cprm .file = no_free_ptr (file );
1065-
1066- if (!coredump_request (& cn , & cprm ))
1067- goto close_fail ;
1068- #else
1069- coredump_report_failure ("Core dump socket support %s disabled" , cn .corename );
1070- goto close_fail ;
1071- #endif
10721082 break ;
1073- }
10741083 default :
10751084 WARN_ON_ONCE (true);
10761085 goto close_fail ;
0 commit comments