Skip to content

Commit d4fde20

Browse files
committed
coredump: massage do_coredump()
We're going to extend the coredump code in follow-up patches. Clean it up so we can do this more easily. Link: https://lore.kernel.org/[email protected] Acked-by: Luca Boccassi <[email protected]> Reviewed-by: Jann Horn <[email protected]> Reviewed-by: Alexander Mikhalitsyn <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent 727b551 commit d4fde20

File tree

1 file changed

+65
-57
lines changed

1 file changed

+65
-57
lines changed

fs/coredump.c

Lines changed: 65 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -643,63 +643,8 @@ void do_coredump(const kernel_siginfo_t *siginfo)
643643
goto fail_unlock;
644644
}
645645

646-
if (cn.core_type == COREDUMP_PIPE) {
647-
int argi;
648-
int dump_count;
649-
char **helper_argv;
650-
struct subprocess_info *sub_info;
651-
652-
if (cprm.limit == 1) {
653-
/* See umh_coredump_setup() which sets RLIMIT_CORE = 1.
654-
*
655-
* Normally core limits are irrelevant to pipes, since
656-
* we're not writing to the file system, but we use
657-
* cprm.limit of 1 here as a special value, this is a
658-
* consistent way to catch recursive crashes.
659-
* We can still crash if the core_pattern binary sets
660-
* RLIM_CORE = !1, but it runs as root, and can do
661-
* lots of stupid things.
662-
*
663-
* Note that we use task_tgid_vnr here to grab the pid
664-
* of the process group leader. That way we get the
665-
* right pid if a thread in a multi-threaded
666-
* core_pattern process dies.
667-
*/
668-
coredump_report_failure("RLIMIT_CORE is set to 1, aborting core");
669-
goto fail_unlock;
670-
}
671-
cprm.limit = RLIM_INFINITY;
672-
673-
dump_count = atomic_inc_return(&core_dump_count);
674-
if (core_pipe_limit && (core_pipe_limit < dump_count)) {
675-
coredump_report_failure("over core_pipe_limit, skipping core dump");
676-
goto fail_dropcount;
677-
}
678-
679-
helper_argv = kmalloc_array(argc + 1, sizeof(*helper_argv),
680-
GFP_KERNEL);
681-
if (!helper_argv) {
682-
coredump_report_failure("%s failed to allocate memory", __func__);
683-
goto fail_dropcount;
684-
}
685-
for (argi = 0; argi < argc; argi++)
686-
helper_argv[argi] = cn.corename + argv[argi];
687-
helper_argv[argi] = NULL;
688-
689-
retval = -ENOMEM;
690-
sub_info = call_usermodehelper_setup(helper_argv[0],
691-
helper_argv, NULL, GFP_KERNEL,
692-
umh_coredump_setup, NULL, &cprm);
693-
if (sub_info)
694-
retval = call_usermodehelper_exec(sub_info,
695-
UMH_WAIT_EXEC);
696-
697-
kfree(helper_argv);
698-
if (retval) {
699-
coredump_report_failure("|%s pipe failed", cn.corename);
700-
goto close_fail;
701-
}
702-
} else if (cn.core_type == COREDUMP_FILE) {
646+
switch (cn.core_type) {
647+
case COREDUMP_FILE: {
703648
struct mnt_idmap *idmap;
704649
struct inode *inode;
705650
int open_flags = O_CREAT | O_WRONLY | O_NOFOLLOW |
@@ -793,6 +738,69 @@ void do_coredump(const kernel_siginfo_t *siginfo)
793738
if (do_truncate(idmap, cprm.file->f_path.dentry,
794739
0, 0, cprm.file))
795740
goto close_fail;
741+
break;
742+
}
743+
case COREDUMP_PIPE: {
744+
int argi;
745+
int dump_count;
746+
char **helper_argv;
747+
struct subprocess_info *sub_info;
748+
749+
if (cprm.limit == 1) {
750+
/* See umh_coredump_setup() which sets RLIMIT_CORE = 1.
751+
*
752+
* Normally core limits are irrelevant to pipes, since
753+
* we're not writing to the file system, but we use
754+
* cprm.limit of 1 here as a special value, this is a
755+
* consistent way to catch recursive crashes.
756+
* We can still crash if the core_pattern binary sets
757+
* RLIM_CORE = !1, but it runs as root, and can do
758+
* lots of stupid things.
759+
*
760+
* Note that we use task_tgid_vnr here to grab the pid
761+
* of the process group leader. That way we get the
762+
* right pid if a thread in a multi-threaded
763+
* core_pattern process dies.
764+
*/
765+
coredump_report_failure("RLIMIT_CORE is set to 1, aborting core");
766+
goto fail_unlock;
767+
}
768+
cprm.limit = RLIM_INFINITY;
769+
770+
dump_count = atomic_inc_return(&core_dump_count);
771+
if (core_pipe_limit && (core_pipe_limit < dump_count)) {
772+
coredump_report_failure("over core_pipe_limit, skipping core dump");
773+
goto fail_dropcount;
774+
}
775+
776+
helper_argv = kmalloc_array(argc + 1, sizeof(*helper_argv),
777+
GFP_KERNEL);
778+
if (!helper_argv) {
779+
coredump_report_failure("%s failed to allocate memory", __func__);
780+
goto fail_dropcount;
781+
}
782+
for (argi = 0; argi < argc; argi++)
783+
helper_argv[argi] = cn.corename + argv[argi];
784+
helper_argv[argi] = NULL;
785+
786+
retval = -ENOMEM;
787+
sub_info = call_usermodehelper_setup(helper_argv[0],
788+
helper_argv, NULL, GFP_KERNEL,
789+
umh_coredump_setup, NULL, &cprm);
790+
if (sub_info)
791+
retval = call_usermodehelper_exec(sub_info,
792+
UMH_WAIT_EXEC);
793+
794+
kfree(helper_argv);
795+
if (retval) {
796+
coredump_report_failure("|%s pipe failed", cn.corename);
797+
goto close_fail;
798+
}
799+
break;
800+
}
801+
default:
802+
WARN_ON_ONCE(true);
803+
goto close_fail;
796804
}
797805

798806
/* get us an unshared descriptor table; almost always a no-op */

0 commit comments

Comments
 (0)