From: Greg Kroah-Hartman Date: Mon, 2 Jun 2025 12:45:43 +0000 (+0200) Subject: 6.6-stable patches X-Git-Tag: v5.4.294~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a54713705d59266cae96e9add3f14f8b41dbf1b7;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: coredump-fix-error-handling-for-replace_fd.patch coredump-hand-a-pidfd-to-the-usermode-coredump-helper.patch --- diff --git a/queue-6.6/coredump-fix-error-handling-for-replace_fd.patch b/queue-6.6/coredump-fix-error-handling-for-replace_fd.patch new file mode 100644 index 0000000000..f9b003e55f --- /dev/null +++ b/queue-6.6/coredump-fix-error-handling-for-replace_fd.patch @@ -0,0 +1,52 @@ +From 07cc2ab8868e15c869b4af7bbe49a0b7ae2a8a1e Mon Sep 17 00:00:00 2001 +From: Christian Brauner +Date: Mon, 14 Apr 2025 15:55:06 +0200 +Subject: coredump: fix error handling for replace_fd() + +From: Christian Brauner + +commit 95c5f43181fe9c1b5e5a4bd3281c857a5259991f upstream. + +The replace_fd() helper returns the file descriptor number on success +and a negative error code on failure. The current error handling in +umh_pipe_setup() only works because the file descriptor that is replaced +is zero but that's pretty volatile. Explicitly check for a negative +error code. + +Link: https://lore.kernel.org/20250414-work-coredump-v2-2-685bf231f828@kernel.org +Tested-by: Luca Boccassi +Reviewed-by: Oleg Nesterov +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman +--- + fs/coredump.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/fs/coredump.c ++++ b/fs/coredump.c +@@ -502,7 +502,9 @@ static int umh_pipe_setup(struct subproc + { + struct file *files[2]; + struct coredump_params *cp = (struct coredump_params *)info->data; +- int err = create_pipe_files(files, 0); ++ int err; ++ ++ err = create_pipe_files(files, 0); + if (err) + return err; + +@@ -510,10 +512,13 @@ static int umh_pipe_setup(struct subproc + + err = replace_fd(0, files[0], 0); + fput(files[0]); ++ if (err < 0) ++ return err; ++ + /* and disallow core files too */ + current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1}; + +- return err; ++ return 0; + } + + void do_coredump(const kernel_siginfo_t *siginfo) diff --git a/queue-6.6/coredump-hand-a-pidfd-to-the-usermode-coredump-helper.patch b/queue-6.6/coredump-hand-a-pidfd-to-the-usermode-coredump-helper.patch new file mode 100644 index 0000000000..78bf054d0f --- /dev/null +++ b/queue-6.6/coredump-hand-a-pidfd-to-the-usermode-coredump-helper.patch @@ -0,0 +1,201 @@ +From 05d1f1d0c42b0d5ecdffbaa986d053f9024b6b19 Mon Sep 17 00:00:00 2001 +From: Christian Brauner +Date: Mon, 14 Apr 2025 15:55:07 +0200 +Subject: coredump: hand a pidfd to the usermode coredump helper + +From: Christian Brauner + +commit b5325b2a270fcaf7b2a9a0f23d422ca8a5a8bdea upstream. + +Give userspace a way to instruct the kernel to install a pidfd into the +usermode helper process. This makes coredump handling a lot more +reliable for userspace. In parallel with this commit we already have +systemd adding support for this in [1]. + +We create a pidfs file for the coredumping process when we process the +corename pattern. When the usermode helper process is forked we then +install the pidfs file as file descriptor three into the usermode +helpers file descriptor table so it's available to the exec'd program. + +Since usermode helpers are either children of the system_unbound_wq +workqueue or kthreadd we know that the file descriptor table is empty +and can thus always use three as the file descriptor number. + +Note, that we'll install a pidfd for the thread-group leader even if a +subthread is calling do_coredump(). We know that task linkage hasn't +been removed due to delay_group_leader() and even if this @current isn't +the actual thread-group leader we know that the thread-group leader +cannot be reaped until @current has exited. + +[brauner: This is a backport for the v6.6 series. Upsteam has +significantly changed and backporting all that infra is a non-starter. +So simply use the pidfd_prepare() helper and waste the file descriptor +we allocated. Then we minimally massage the umh coredump setup code.] + +Link: https://github.com/systemd/systemd/pull/37125 [1] +Link: https://lore.kernel.org/20250414-work-coredump-v2-3-685bf231f828@kernel.org +Tested-by: Luca Boccassi +Reviewed-by: Oleg Nesterov +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman +--- + fs/coredump.c | 78 ++++++++++++++++++++++++++++++++++++++++++----- + include/linux/coredump.h | 1 + 2 files changed, 72 insertions(+), 7 deletions(-) + +--- a/fs/coredump.c ++++ b/fs/coredump.c +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -56,6 +57,13 @@ + static bool dump_vma_snapshot(struct coredump_params *cprm); + static void free_vma_snapshot(struct coredump_params *cprm); + ++/* ++ * File descriptor number for the pidfd for the thread-group leader of ++ * the coredumping task installed into the usermode helper's file ++ * descriptor table. ++ */ ++#define COREDUMP_PIDFD_NUMBER 3 ++ + static int core_uses_pid; + static unsigned int core_pipe_limit; + static char core_pattern[CORENAME_MAX_SIZE] = "core"; +@@ -332,6 +340,27 @@ static int format_corename(struct core_n + case 'C': + err = cn_printf(cn, "%d", cprm->cpu); + break; ++ /* pidfd number */ ++ case 'F': { ++ /* ++ * Installing a pidfd only makes sense if ++ * we actually spawn a usermode helper. ++ */ ++ if (!ispipe) ++ break; ++ ++ /* ++ * Note that we'll install a pidfd for the ++ * thread-group leader. We know that task ++ * linkage hasn't been removed yet and even if ++ * this @current isn't the actual thread-group ++ * leader we know that the thread-group leader ++ * cannot be reaped until @current has exited. ++ */ ++ cprm->pid = task_tgid(current); ++ err = cn_printf(cn, "%d", COREDUMP_PIDFD_NUMBER); ++ break; ++ } + default: + break; + } +@@ -488,7 +517,7 @@ static void wait_for_dump_helpers(struct + } + + /* +- * umh_pipe_setup ++ * umh_coredump_setup + * helper function to customize the process used + * to collect the core in userspace. Specifically + * it sets up a pipe and installs it as fd 0 (stdin) +@@ -498,27 +527,62 @@ static void wait_for_dump_helpers(struct + * is a special value that we use to trap recursive + * core dumps + */ +-static int umh_pipe_setup(struct subprocess_info *info, struct cred *new) ++static int umh_coredump_setup(struct subprocess_info *info, struct cred *new) + { + struct file *files[2]; ++ struct file *pidfs_file = NULL; + struct coredump_params *cp = (struct coredump_params *)info->data; + int err; + ++ if (cp->pid) { ++ int fd; ++ ++ fd = pidfd_prepare(cp->pid, 0, &pidfs_file); ++ if (fd < 0) ++ return fd; ++ ++ /* ++ * We don't care about the fd. We also cannot simply ++ * replace it below because dup2() will refuse to close ++ * this file descriptor if its in a larval state. So ++ * close it! ++ */ ++ put_unused_fd(fd); ++ ++ /* ++ * Usermode helpers are childen of either ++ * system_unbound_wq or of kthreadd. So we know that ++ * we're starting off with a clean file descriptor ++ * table. So we should always be able to use ++ * COREDUMP_PIDFD_NUMBER as our file descriptor value. ++ */ ++ err = replace_fd(COREDUMP_PIDFD_NUMBER, pidfs_file, 0); ++ if (err < 0) ++ goto out_fail; ++ ++ pidfs_file = NULL; ++ } ++ + err = create_pipe_files(files, 0); + if (err) +- return err; ++ goto out_fail; + + cp->file = files[1]; + + err = replace_fd(0, files[0], 0); + fput(files[0]); + if (err < 0) +- return err; ++ goto out_fail; + + /* and disallow core files too */ + current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1}; + +- return 0; ++ err = 0; ++ ++out_fail: ++ if (pidfs_file) ++ fput(pidfs_file); ++ return err; + } + + void do_coredump(const kernel_siginfo_t *siginfo) +@@ -594,7 +658,7 @@ void do_coredump(const kernel_siginfo_t + } + + if (cprm.limit == 1) { +- /* See umh_pipe_setup() which sets RLIMIT_CORE = 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 +@@ -639,7 +703,7 @@ void do_coredump(const kernel_siginfo_t + retval = -ENOMEM; + sub_info = call_usermodehelper_setup(helper_argv[0], + helper_argv, NULL, GFP_KERNEL, +- umh_pipe_setup, NULL, &cprm); ++ umh_coredump_setup, NULL, &cprm); + if (sub_info) + retval = call_usermodehelper_exec(sub_info, + UMH_WAIT_EXEC); +--- a/include/linux/coredump.h ++++ b/include/linux/coredump.h +@@ -28,6 +28,7 @@ struct coredump_params { + int vma_count; + size_t vma_data_size; + struct core_vma_metadata *vma_meta; ++ struct pid *pid; + }; + + /* diff --git a/queue-6.6/series b/queue-6.6/series index 49518f556d..3d59784a17 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -426,3 +426,5 @@ arm64-dts-ti-k3-am68-sk-fix-regulator-hierarchy.patch net_sched-hfsc-address-reentrant-enqueue-adding-class-to-eltree-twice.patch perf-arm-cmn-fix-req2-snp2-mixup.patch perf-arm-cmn-initialise-cmn-cpu-earlier.patch +coredump-fix-error-handling-for-replace_fd.patch +coredump-hand-a-pidfd-to-the-usermode-coredump-helper.patch