@@ -970,6 +970,63 @@ static bool coredump_file(struct core_name *cn, struct coredump_params *cprm,
970970 return true;
971971}
972972
973+ static bool coredump_pipe (struct core_name * cn , struct coredump_params * cprm ,
974+ size_t * argv , int argc )
975+ {
976+ int argi ;
977+ char * * helper_argv __free (kfree ) = NULL ;
978+ struct subprocess_info * sub_info ;
979+
980+ if (cprm -> limit == 1 ) {
981+ /* See umh_coredump_setup() which sets RLIMIT_CORE = 1.
982+ *
983+ * Normally core limits are irrelevant to pipes, since
984+ * we're not writing to the file system, but we use
985+ * cprm.limit of 1 here as a special value, this is a
986+ * consistent way to catch recursive crashes.
987+ * We can still crash if the core_pattern binary sets
988+ * RLIM_CORE = !1, but it runs as root, and can do
989+ * lots of stupid things.
990+ *
991+ * Note that we use task_tgid_vnr here to grab the pid
992+ * of the process group leader. That way we get the
993+ * right pid if a thread in a multi-threaded
994+ * core_pattern process dies.
995+ */
996+ coredump_report_failure ("RLIMIT_CORE is set to 1, aborting core" );
997+ return false;
998+ }
999+ cprm -> limit = RLIM_INFINITY ;
1000+
1001+ cn -> core_pipe_limit = atomic_inc_return (& core_pipe_count );
1002+ if (core_pipe_limit && (core_pipe_limit < cn -> core_pipe_limit )) {
1003+ coredump_report_failure ("over core_pipe_limit, skipping core dump" );
1004+ return false;
1005+ }
1006+
1007+ helper_argv = kmalloc_array (argc + 1 , sizeof (* helper_argv ), GFP_KERNEL );
1008+ if (!helper_argv ) {
1009+ coredump_report_failure ("%s failed to allocate memory" , __func__ );
1010+ return false;
1011+ }
1012+ for (argi = 0 ; argi < argc ; argi ++ )
1013+ helper_argv [argi ] = cn -> corename + argv [argi ];
1014+ helper_argv [argi ] = NULL ;
1015+
1016+ sub_info = call_usermodehelper_setup (helper_argv [0 ], helper_argv , NULL ,
1017+ GFP_KERNEL , umh_coredump_setup ,
1018+ NULL , cprm );
1019+ if (!sub_info )
1020+ return false;
1021+
1022+ if (call_usermodehelper_exec (sub_info , UMH_WAIT_EXEC )) {
1023+ coredump_report_failure ("|%s pipe failed" , cn -> corename );
1024+ return false;
1025+ }
1026+
1027+ return true;
1028+ }
1029+
9731030void vfs_coredump (const kernel_siginfo_t * siginfo )
9741031{
9751032 struct core_state core_state ;
@@ -1031,63 +1088,10 @@ void vfs_coredump(const kernel_siginfo_t *siginfo)
10311088 if (!coredump_file (& cn , & cprm , binfmt ))
10321089 goto close_fail ;
10331090 break ;
1034- case COREDUMP_PIPE : {
1035- int argi ;
1036- char * * helper_argv ;
1037- struct subprocess_info * sub_info ;
1038-
1039- if (cprm .limit == 1 ) {
1040- /* See umh_coredump_setup() which sets RLIMIT_CORE = 1.
1041- *
1042- * Normally core limits are irrelevant to pipes, since
1043- * we're not writing to the file system, but we use
1044- * cprm.limit of 1 here as a special value, this is a
1045- * consistent way to catch recursive crashes.
1046- * We can still crash if the core_pattern binary sets
1047- * RLIM_CORE = !1, but it runs as root, and can do
1048- * lots of stupid things.
1049- *
1050- * Note that we use task_tgid_vnr here to grab the pid
1051- * of the process group leader. That way we get the
1052- * right pid if a thread in a multi-threaded
1053- * core_pattern process dies.
1054- */
1055- coredump_report_failure ("RLIMIT_CORE is set to 1, aborting core" );
1056- goto close_fail ;
1057- }
1058- cprm .limit = RLIM_INFINITY ;
1059-
1060- cn .core_pipe_limit = atomic_inc_return (& core_pipe_count );
1061- if (core_pipe_limit && (core_pipe_limit < cn .core_pipe_limit )) {
1062- coredump_report_failure ("over core_pipe_limit, skipping core dump" );
1091+ case COREDUMP_PIPE :
1092+ if (!coredump_pipe (& cn , & cprm , argv , argc ))
10631093 goto close_fail ;
1064- }
1065-
1066- helper_argv = kmalloc_array (argc + 1 , sizeof (* helper_argv ),
1067- GFP_KERNEL );
1068- if (!helper_argv ) {
1069- coredump_report_failure ("%s failed to allocate memory" , __func__ );
1070- goto close_fail ;
1071- }
1072- for (argi = 0 ; argi < argc ; argi ++ )
1073- helper_argv [argi ] = cn .corename + argv [argi ];
1074- helper_argv [argi ] = NULL ;
1075-
1076- retval = - ENOMEM ;
1077- sub_info = call_usermodehelper_setup (helper_argv [0 ],
1078- helper_argv , NULL , GFP_KERNEL ,
1079- umh_coredump_setup , NULL , & cprm );
1080- if (sub_info )
1081- retval = call_usermodehelper_exec (sub_info ,
1082- UMH_WAIT_EXEC );
1083-
1084- kfree (helper_argv );
1085- if (retval ) {
1086- coredump_report_failure ("|%s pipe failed" , cn .corename );
1087- goto close_fail ;
1088- }
10891094 break ;
1090- }
10911095 case COREDUMP_SOCK_REQ :
10921096 fallthrough ;
10931097 case COREDUMP_SOCK :
0 commit comments