]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
objtool: Fix another stack overflow in validate_branch()
authorJosh Poimboeuf <jpoimboe@kernel.org>
Fri, 6 Mar 2026 18:28:14 +0000 (10:28 -0800)
committerJosh Poimboeuf <jpoimboe@kernel.org>
Mon, 9 Mar 2026 15:45:13 +0000 (08:45 -0700)
The insn state is getting saved on the stack twice for each recursive
iteration.  No need for that, once is enough.

Fixes the following reported stack overflow:

  drivers/scsi/qla2xxx/qla_dbg.o: error: SIGSEGV: objtool stack overflow!
  Segmentation fault

Fixes: 70589843b36f ("objtool: Add option to trace function validation")
Reported-by: Arnd Bergmann <arnd@arndb.de>
Closes: https://lore.kernel.org/90956545-2066-46e3-b547-10c884582eb0@app.fastmail.com
Link: https://patch.msgid.link/8b97f62d083457f3b0a29a424275f7957dd3372f.1772821683.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
tools/objtool/check.c

index 786b2f2adbab6b4879063a4c82df9154cd3abf4a..91b3ff4803cf2773c21b89ed9be52d77118e7b47 100644 (file)
@@ -3748,7 +3748,7 @@ static void checksum_update_insn(struct objtool_file *file, struct symbol *func,
 static int validate_branch(struct objtool_file *file, struct symbol *func,
                           struct instruction *insn, struct insn_state state);
 static int do_validate_branch(struct objtool_file *file, struct symbol *func,
-                             struct instruction *insn, struct insn_state state);
+                             struct instruction *insn, struct insn_state *state);
 
 static int validate_insn(struct objtool_file *file, struct symbol *func,
                         struct instruction *insn, struct insn_state *statep,
@@ -4013,7 +4013,7 @@ static int validate_insn(struct objtool_file *file, struct symbol *func,
  * tools/objtool/Documentation/objtool.txt.
  */
 static int do_validate_branch(struct objtool_file *file, struct symbol *func,
-                             struct instruction *insn, struct insn_state state)
+                             struct instruction *insn, struct insn_state *state)
 {
        struct instruction *next_insn, *prev_insn = NULL;
        bool dead_end;
@@ -4044,7 +4044,7 @@ static int do_validate_branch(struct objtool_file *file, struct symbol *func,
                        return 1;
                }
 
-               ret = validate_insn(file, func, insn, &state, prev_insn, next_insn,
+               ret = validate_insn(file, func, insn, state, prev_insn, next_insn,
                                    &dead_end);
 
                if (!insn->trace) {
@@ -4055,7 +4055,7 @@ static int do_validate_branch(struct objtool_file *file, struct symbol *func,
                }
 
                if (!dead_end && !next_insn) {
-                       if (state.cfi.cfa.base == CFI_UNDEFINED)
+                       if (state->cfi.cfa.base == CFI_UNDEFINED)
                                return 0;
                        if (file->ignore_unreachables)
                                return 0;
@@ -4080,7 +4080,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
        int ret;
 
        trace_depth_inc();
-       ret = do_validate_branch(file, func, insn, state);
+       ret = do_validate_branch(file, func, insn, &state);
        trace_depth_dec();
 
        return ret;