mirror of
https://github.com/torvalds/linux.git
synced 2026-07-29 18:51:21 +02:00
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/20250516-work-coredump-socket-v8-2-664f3caf2516@kernel.org Acked-by: Luca Boccassi <luca.boccassi@gmail.com> Reviewed-by: Jann Horn <jannh@google.com> Reviewed-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
727b55105a
commit
d4fde206ab
122
fs/coredump.c
122
fs/coredump.c
|
|
@ -643,63 +643,8 @@ void do_coredump(const kernel_siginfo_t *siginfo)
|
|||
goto fail_unlock;
|
||||
}
|
||||
|
||||
if (cn.core_type == COREDUMP_PIPE) {
|
||||
int argi;
|
||||
int dump_count;
|
||||
char **helper_argv;
|
||||
struct subprocess_info *sub_info;
|
||||
|
||||
if (cprm.limit == 1) {
|
||||
/* See umh_coredump_setup() which sets RLIMIT_CORE = 1.
|
||||
*
|
||||
* Normally core limits are irrelevant to pipes, since
|
||||
* we're not writing to the file system, but we use
|
||||
* cprm.limit of 1 here as a special value, this is a
|
||||
* consistent way to catch recursive crashes.
|
||||
* We can still crash if the core_pattern binary sets
|
||||
* RLIM_CORE = !1, but it runs as root, and can do
|
||||
* lots of stupid things.
|
||||
*
|
||||
* Note that we use task_tgid_vnr here to grab the pid
|
||||
* of the process group leader. That way we get the
|
||||
* right pid if a thread in a multi-threaded
|
||||
* core_pattern process dies.
|
||||
*/
|
||||
coredump_report_failure("RLIMIT_CORE is set to 1, aborting core");
|
||||
goto fail_unlock;
|
||||
}
|
||||
cprm.limit = RLIM_INFINITY;
|
||||
|
||||
dump_count = atomic_inc_return(&core_dump_count);
|
||||
if (core_pipe_limit && (core_pipe_limit < dump_count)) {
|
||||
coredump_report_failure("over core_pipe_limit, skipping core dump");
|
||||
goto fail_dropcount;
|
||||
}
|
||||
|
||||
helper_argv = kmalloc_array(argc + 1, sizeof(*helper_argv),
|
||||
GFP_KERNEL);
|
||||
if (!helper_argv) {
|
||||
coredump_report_failure("%s failed to allocate memory", __func__);
|
||||
goto fail_dropcount;
|
||||
}
|
||||
for (argi = 0; argi < argc; argi++)
|
||||
helper_argv[argi] = cn.corename + argv[argi];
|
||||
helper_argv[argi] = NULL;
|
||||
|
||||
retval = -ENOMEM;
|
||||
sub_info = call_usermodehelper_setup(helper_argv[0],
|
||||
helper_argv, NULL, GFP_KERNEL,
|
||||
umh_coredump_setup, NULL, &cprm);
|
||||
if (sub_info)
|
||||
retval = call_usermodehelper_exec(sub_info,
|
||||
UMH_WAIT_EXEC);
|
||||
|
||||
kfree(helper_argv);
|
||||
if (retval) {
|
||||
coredump_report_failure("|%s pipe failed", cn.corename);
|
||||
goto close_fail;
|
||||
}
|
||||
} else if (cn.core_type == COREDUMP_FILE) {
|
||||
switch (cn.core_type) {
|
||||
case COREDUMP_FILE: {
|
||||
struct mnt_idmap *idmap;
|
||||
struct inode *inode;
|
||||
int open_flags = O_CREAT | O_WRONLY | O_NOFOLLOW |
|
||||
|
|
@ -793,6 +738,69 @@ void do_coredump(const kernel_siginfo_t *siginfo)
|
|||
if (do_truncate(idmap, cprm.file->f_path.dentry,
|
||||
0, 0, cprm.file))
|
||||
goto close_fail;
|
||||
break;
|
||||
}
|
||||
case COREDUMP_PIPE: {
|
||||
int argi;
|
||||
int dump_count;
|
||||
char **helper_argv;
|
||||
struct subprocess_info *sub_info;
|
||||
|
||||
if (cprm.limit == 1) {
|
||||
/* See umh_coredump_setup() which sets RLIMIT_CORE = 1.
|
||||
*
|
||||
* Normally core limits are irrelevant to pipes, since
|
||||
* we're not writing to the file system, but we use
|
||||
* cprm.limit of 1 here as a special value, this is a
|
||||
* consistent way to catch recursive crashes.
|
||||
* We can still crash if the core_pattern binary sets
|
||||
* RLIM_CORE = !1, but it runs as root, and can do
|
||||
* lots of stupid things.
|
||||
*
|
||||
* Note that we use task_tgid_vnr here to grab the pid
|
||||
* of the process group leader. That way we get the
|
||||
* right pid if a thread in a multi-threaded
|
||||
* core_pattern process dies.
|
||||
*/
|
||||
coredump_report_failure("RLIMIT_CORE is set to 1, aborting core");
|
||||
goto fail_unlock;
|
||||
}
|
||||
cprm.limit = RLIM_INFINITY;
|
||||
|
||||
dump_count = atomic_inc_return(&core_dump_count);
|
||||
if (core_pipe_limit && (core_pipe_limit < dump_count)) {
|
||||
coredump_report_failure("over core_pipe_limit, skipping core dump");
|
||||
goto fail_dropcount;
|
||||
}
|
||||
|
||||
helper_argv = kmalloc_array(argc + 1, sizeof(*helper_argv),
|
||||
GFP_KERNEL);
|
||||
if (!helper_argv) {
|
||||
coredump_report_failure("%s failed to allocate memory", __func__);
|
||||
goto fail_dropcount;
|
||||
}
|
||||
for (argi = 0; argi < argc; argi++)
|
||||
helper_argv[argi] = cn.corename + argv[argi];
|
||||
helper_argv[argi] = NULL;
|
||||
|
||||
retval = -ENOMEM;
|
||||
sub_info = call_usermodehelper_setup(helper_argv[0],
|
||||
helper_argv, NULL, GFP_KERNEL,
|
||||
umh_coredump_setup, NULL, &cprm);
|
||||
if (sub_info)
|
||||
retval = call_usermodehelper_exec(sub_info,
|
||||
UMH_WAIT_EXEC);
|
||||
|
||||
kfree(helper_argv);
|
||||
if (retval) {
|
||||
coredump_report_failure("|%s pipe failed", cn.corename);
|
||||
goto close_fail;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
WARN_ON_ONCE(true);
|
||||
goto close_fail;
|
||||
}
|
||||
|
||||
/* get us an unshared descriptor table; almost always a no-op */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user