All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] objtool: Fix stack overflow in validate_branch()
@ 2025-12-02 16:16 Josh Poimboeuf
  2025-12-02 16:20 ` Ingo Molnar
                   ` (3 more replies)
  0 siblings, 4 replies; 26+ messages in thread
From: Josh Poimboeuf @ 2025-12-02 16:16 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Nathan Chancellor, Peter Zijlstra,
	Alexandre Chartre, Ingo Molnar, David Laight

On an allmodconfig kernel compiled with Clang, objtool is segfaulting in
drivers/scsi/qla2xxx/qla2xxx.o due to a stack overflow in
validate_branch().

Due in part to KASAN being enabled, the qla2xxx code has a large number
of conditional jumps, causing objtool to go quite deep in its recursion.

By far the biggest offender of stack usage is the recently added
'prev_state' stack variable in validate_insn(), coming in at 328 bytes.

Move that variable (and its tracing usage) to handle_insn_ops() and make
handle_insn_ops() noinline to keep its stack frame outside the recursive
call chain.

Fixes: fcb268b47a2f ("objtool: Trace instruction state changes during function validation")
Reported-by: Nathan Chancellor <nathan@kernel.org>
Closes: https://lore.kernel.org/20251201202329.GA3225984@ax162
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 tools/objtool/check.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 9ec0e07cce90..4e7b44f13b8c 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -3282,18 +3282,19 @@ static int propagate_alt_cfi(struct objtool_file *file, struct instruction *insn
 	return 0;
 }
 
-static int handle_insn_ops(struct instruction *insn,
-			   struct instruction *next_insn,
-			   struct insn_state *state)
+static int noinline handle_insn_ops(struct instruction *insn,
+				    struct instruction *next_insn,
+				    struct insn_state *state)
 {
+	struct insn_state prev_state __maybe_unused = *state;
 	struct stack_op *op;
-	int ret;
+	int ret = 0;
 
 	for (op = insn->stack_ops; op; op = op->next) {
 
 		ret = update_cfi_state(insn, next_insn, &state->cfi, op);
 		if (ret)
-			return ret;
+			goto done;
 
 		if (!opts.uaccess || !insn->alt_group)
 			continue;
@@ -3303,7 +3304,8 @@ static int handle_insn_ops(struct instruction *insn,
 				state->uaccess_stack = 1;
 			} else if (state->uaccess_stack >> 31) {
 				WARN_INSN(insn, "PUSHF stack exhausted");
-				return 1;
+				ret = 1;
+				goto done;
 			}
 			state->uaccess_stack <<= 1;
 			state->uaccess_stack  |= state->uaccess;
@@ -3319,6 +3321,8 @@ static int handle_insn_ops(struct instruction *insn,
 		}
 	}
 
+done:
+	TRACE_INSN_STATE(insn, &prev_state, state);
 	return 0;
 }
 
@@ -3694,8 +3698,6 @@ static int validate_insn(struct objtool_file *file, struct symbol *func,
 			 struct instruction *prev_insn, struct instruction *next_insn,
 			 bool *dead_end)
 {
-	/* prev_state and alt_name are not used if there is no disassembly support */
-	struct insn_state prev_state __maybe_unused;
 	char *alt_name __maybe_unused = NULL;
 	struct alternative *alt;
 	u8 visited;
@@ -3798,11 +3800,7 @@ static int validate_insn(struct objtool_file *file, struct symbol *func,
 	if (skip_alt_group(insn))
 		return 0;
 
-	prev_state = *statep;
-	ret = handle_insn_ops(insn, next_insn, statep);
-	TRACE_INSN_STATE(insn, &prev_state, statep);
-
-	if (ret)
+	if (handle_insn_ops(insn, next_insn, statep))
 		return 1;
 
 	switch (insn->type) {
-- 
2.51.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2025-12-04  2:47 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-02 16:16 [PATCH] objtool: Fix stack overflow in validate_branch() Josh Poimboeuf
2025-12-02 16:20 ` Ingo Molnar
2025-12-02 16:49   ` Josh Poimboeuf
2025-12-02 17:03     ` Ingo Molnar
2025-12-02 17:11       ` Josh Poimboeuf
2025-12-02 19:56         ` Josh Poimboeuf
2025-12-02 20:20           ` Ingo Molnar
2025-12-02 22:05             ` David Laight
2025-12-02 23:01               ` Josh Poimboeuf
2025-12-03 11:02                 ` David Laight
2025-12-03 16:11                 ` Ingo Molnar
2025-12-03 16:40                 ` [tip: objtool/urgent] objtool: Add more robust signal error handling, detect and warn about stack overflows tip-bot2 for Josh Poimboeuf
2025-12-03 18:48                 ` tip-bot2 for Josh Poimboeuf
2025-12-03  9:25     ` [PATCH] objtool: Fix stack overflow in validate_branch() Ingo Molnar
2025-12-03 18:54       ` Josh Poimboeuf
2025-12-03 18:58         ` Josh Poimboeuf
2025-12-03 19:15           ` Ingo Molnar
2025-12-03 19:37             ` David Laight
2025-12-03 20:30               ` Linus Torvalds
2025-12-03 23:53             ` Josh Poimboeuf
2025-12-03 19:11         ` Ingo Molnar
2025-12-04  2:47           ` Josh Poimboeuf
2025-12-02 16:27 ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
2025-12-02 16:28 ` [PATCH] " Josh Poimboeuf
2025-12-02 16:41   ` Ingo Molnar
2025-12-02 16:44 ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.