[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250620112105.3396149-1-arnd@kernel.org>
Date: Fri, 20 Jun 2025 13:21:01 +0200
From: Arnd Bergmann <arnd@...nel.org>
To: Alexander Viro <viro@...iv.linux.org.uk>,
Christian Brauner <brauner@...nel.org>
Cc: Arnd Bergmann <arnd@...db.de>,
Jan Kara <jack@...e.cz>,
Alexander Mikhalitsyn <alexander@...alicyn.com>,
Jann Horn <jannh@...gle.com>,
Luca Boccassi <luca.boccassi@...il.com>,
Jeff Layton <jlayton@...nel.org>,
Roman Kisel <romank@...ux.microsoft.com>,
linux-fsdevel@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH] coredump: reduce stack usage in vfs_coredump()
From: Arnd Bergmann <arnd@...db.de>
The newly added socket coredump code runs into some corner cases
with KASAN that end up needing a lot of stack space:
fs/coredump.c:1206:1: error: the frame size of 1680 bytes is larger than 1280 bytes [-Werror=frame-larger-than=]
Mark the socket helper function as noinline_for_stack so its stack
usage does not leak out to the other code paths. This also seems to
help with register pressure, and the resulting combined stack usage of
vfs_coredump() and coredump_socket() is actually lower than the inlined
version.
Moving the core_state variable into coredump_wait() helps reduce the
stack usage further and simplifies the code, though it is not sufficient
to avoid the warning by itself.
Fixes: 6a7a50e5f1ac ("coredump: use a single helper for the socket")
Signed-off-by: Arnd Bergmann <arnd@...db.de>
---
fs/coredump.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/fs/coredump.c b/fs/coredump.c
index e2611fb1f254..c46e3996ff91 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -518,27 +518,28 @@ static int zap_threads(struct task_struct *tsk,
return nr;
}
-static int coredump_wait(int exit_code, struct core_state *core_state)
+static int coredump_wait(int exit_code)
{
struct task_struct *tsk = current;
+ struct core_state core_state;
int core_waiters = -EBUSY;
- init_completion(&core_state->startup);
- core_state->dumper.task = tsk;
- core_state->dumper.next = NULL;
+ init_completion(&core_state.startup);
+ core_state.dumper.task = tsk;
+ core_state.dumper.next = NULL;
- core_waiters = zap_threads(tsk, core_state, exit_code);
+ core_waiters = zap_threads(tsk, &core_state, exit_code);
if (core_waiters > 0) {
struct core_thread *ptr;
- wait_for_completion_state(&core_state->startup,
+ wait_for_completion_state(&core_state.startup,
TASK_UNINTERRUPTIBLE|TASK_FREEZABLE);
/*
* Wait for all the threads to become inactive, so that
* all the thread context (extended register state, like
* fpu etc) gets copied to the memory.
*/
- ptr = core_state->dumper.next;
+ ptr = core_state.dumper.next;
while (ptr != NULL) {
wait_task_inactive(ptr->task, TASK_ANY);
ptr = ptr->next;
@@ -858,7 +859,7 @@ static bool coredump_sock_request(struct core_name *cn, struct coredump_params *
return coredump_sock_mark(cprm->file, COREDUMP_MARK_REQACK);
}
-static bool coredump_socket(struct core_name *cn, struct coredump_params *cprm)
+static noinline_for_stack bool coredump_socket(struct core_name *cn, struct coredump_params *cprm)
{
if (!coredump_sock_connect(cn, cprm))
return false;
@@ -1095,7 +1096,6 @@ void vfs_coredump(const kernel_siginfo_t *siginfo)
{
struct cred *cred __free(put_cred) = NULL;
size_t *argv __free(kfree) = NULL;
- struct core_state core_state;
struct core_name cn;
struct mm_struct *mm = current->mm;
struct linux_binfmt *binfmt = mm->binfmt;
@@ -1131,7 +1131,7 @@ void vfs_coredump(const kernel_siginfo_t *siginfo)
if (coredump_force_suid_safe(&cprm))
cred->fsuid = GLOBAL_ROOT_UID;
- if (coredump_wait(siginfo->si_signo, &core_state) < 0)
+ if (coredump_wait(siginfo->si_signo) < 0)
return;
old_cred = override_creds(cred);
--
2.39.5
Powered by blists - more mailing lists