@@ -646,6 +646,77 @@ static int umh_coredump_setup(struct subprocess_info *info, struct cred *new)
646
646
}
647
647
648
648
#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
+
649
720
static inline bool coredump_sock_recv (struct file * file , struct coredump_ack * ack , size_t size , int flags )
650
721
{
651
722
struct msghdr msg = {};
@@ -707,7 +778,7 @@ static inline void coredump_sock_shutdown(struct file *file)
707
778
kernel_sock_shutdown (socket , SHUT_WR );
708
779
}
709
780
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 )
711
782
{
712
783
struct coredump_req req = {
713
784
.size = sizeof (struct coredump_req ),
@@ -770,6 +841,14 @@ static bool coredump_request(struct core_name *cn, struct coredump_params *cprm)
770
841
return coredump_sock_mark (cprm -> file , COREDUMP_MARK_REQACK );
771
842
}
772
843
#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; }
773
852
static inline void coredump_sock_wait (struct file * file ) { }
774
853
static inline void coredump_sock_shutdown (struct file * file ) { }
775
854
#endif
@@ -994,83 +1073,13 @@ void do_coredump(const kernel_siginfo_t *siginfo)
994
1073
}
995
1074
case COREDUMP_SOCK_REQ :
996
1075
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 ))
1056
1078
goto close_fail ;
1057
- }
1058
1079
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 ))
1061
1081
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
1072
1082
break ;
1073
- }
1074
1083
default :
1075
1084
WARN_ON_ONCE (true);
1076
1085
goto close_fail ;
0 commit comments