Skip to content

Commit 9f29a34

Browse files
committed
coredump: split pipe coredumping into coredump_pipe()
* Move that whole mess into a separate helper instead of having all that hanging around in vfs_coredump() directly. Cleanup paths are already centralized. Link: https://lore.kernel.org/20250612-work-coredump-massage-v1-13-315c0c34ba94@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 4f59921 commit 9f29a34

1 file changed

Lines changed: 59 additions & 55 deletions

File tree

fs/coredump.c

Lines changed: 59 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
9731030
void 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

Comments
 (0)