Unverified Commit 727b5510 authored by Christian Brauner's avatar Christian Brauner
Browse files

coredump: massage format_corename()

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-1-664f3caf2516@kernel.org


Acked-by: default avatarSerge Hallyn <serge@hallyn.com>
Acked-by: default avatarLuca Boccassi <luca.boccassi@gmail.com>
Reviewed-by: default avatarJann Horn <jannh@google.com>
Reviewed-by: default avatarAlexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent 4dd6566b
Loading
Loading
Loading
Loading
+25 −21
Original line number Diff line number Diff line
@@ -76,9 +76,15 @@ static char core_pattern[CORENAME_MAX_SIZE] = "core";
static int core_name_size = CORENAME_MAX_SIZE;
unsigned int core_file_note_size_limit = CORE_FILE_NOTE_SIZE_DEFAULT;

enum coredump_type_t {
	COREDUMP_FILE = 1,
	COREDUMP_PIPE = 2,
};

struct core_name {
	char *corename;
	int used, size;
	enum coredump_type_t core_type;
};

static int expand_corename(struct core_name *cn, int size)
@@ -218,18 +224,21 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm,
{
	const struct cred *cred = current_cred();
	const char *pat_ptr = core_pattern;
	int ispipe = (*pat_ptr == '|');
	bool was_space = false;
	int pid_in_pattern = 0;
	int err = 0;

	cn->used = 0;
	cn->corename = NULL;
	if (*pat_ptr == '|')
		cn->core_type = COREDUMP_PIPE;
	else
		cn->core_type = COREDUMP_FILE;
	if (expand_corename(cn, core_name_size))
		return -ENOMEM;
	cn->corename[0] = '\0';

	if (ispipe) {
	if (cn->core_type == COREDUMP_PIPE) {
		int argvs = sizeof(core_pattern) / 2;
		(*argv) = kmalloc_array(argvs, sizeof(**argv), GFP_KERNEL);
		if (!(*argv))
@@ -247,7 +256,7 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm,
		 * Split on spaces before doing template expansion so that
		 * %e and %E don't get split if they have spaces in them
		 */
		if (ispipe) {
		if (cn->core_type == COREDUMP_PIPE) {
			if (isspace(*pat_ptr)) {
				if (cn->used != 0)
					was_space = true;
@@ -353,7 +362,7 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm,
				 * Installing a pidfd only makes sense if
				 * we actually spawn a usermode helper.
				 */
				if (!ispipe)
				if (cn->core_type != COREDUMP_PIPE)
					break;

				/*
@@ -384,12 +393,9 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm,
	 * If core_pattern does not include a %p (as is the default)
	 * and core_uses_pid is set, then .%pid will be appended to
	 * the filename. Do not do this for piped commands. */
	if (!ispipe && !pid_in_pattern && core_uses_pid) {
		err = cn_printf(cn, ".%d", task_tgid_vnr(current));
		if (err)
			return err;
	}
	return ispipe;
	if (cn->core_type == COREDUMP_FILE && !pid_in_pattern && core_uses_pid)
		return cn_printf(cn, ".%d", task_tgid_vnr(current));
	return 0;
}

static int zap_process(struct signal_struct *signal, int exit_code)
@@ -583,7 +589,6 @@ void do_coredump(const kernel_siginfo_t *siginfo)
	const struct cred *old_cred;
	struct cred *cred;
	int retval = 0;
	int ispipe;
	size_t *argv = NULL;
	int argc = 0;
	/* require nonrelative corefile path and be extra careful */
@@ -632,19 +637,18 @@ void do_coredump(const kernel_siginfo_t *siginfo)

	old_cred = override_creds(cred);

	ispipe = format_corename(&cn, &cprm, &argv, &argc);
	retval = format_corename(&cn, &cprm, &argv, &argc);
	if (retval < 0) {
		coredump_report_failure("format_corename failed, aborting core");
		goto fail_unlock;
	}

	if (ispipe) {
	if (cn.core_type == COREDUMP_PIPE) {
		int argi;
		int dump_count;
		char **helper_argv;
		struct subprocess_info *sub_info;

		if (ispipe < 0) {
			coredump_report_failure("format_corename failed, aborting core");
			goto fail_unlock;
		}

		if (cprm.limit == 1) {
			/* See umh_coredump_setup() which sets RLIMIT_CORE = 1.
			 *
@@ -695,7 +699,7 @@ void do_coredump(const kernel_siginfo_t *siginfo)
			coredump_report_failure("|%s pipe failed", cn.corename);
			goto close_fail;
		}
	} else {
	} else if (cn.core_type == COREDUMP_FILE) {
		struct mnt_idmap *idmap;
		struct inode *inode;
		int open_flags = O_CREAT | O_WRONLY | O_NOFOLLOW |
@@ -823,13 +827,13 @@ void do_coredump(const kernel_siginfo_t *siginfo)
		file_end_write(cprm.file);
		free_vma_snapshot(&cprm);
	}
	if (ispipe && core_pipe_limit)
	if ((cn.core_type == COREDUMP_PIPE) && core_pipe_limit)
		wait_for_dump_helpers(cprm.file);
close_fail:
	if (cprm.file)
		filp_close(cprm.file, NULL);
fail_dropcount:
	if (ispipe)
	if (cn.core_type == COREDUMP_PIPE)
		atomic_dec(&core_dump_count);
fail_unlock:
	kfree(argv);