objtool: Fix segfault in ignore_unreachable_insn()

"Linux Kernel Mailing List" <[email protected]> Thu, 15 Feb 2018 01:31:43 +0000 (UTC)
Newsgroups gmane.linux.kernel.commits.head
Message-ID <[email protected]>
Web:        https://git.kernel.org/torvalds/c/fe24e27128252c230a34a6c628da2bf1676781ea
Commit:     fe24e27128252c230a34a6c628da2bf1676781ea
Parent:     9279ddf23ce78ff2676e8e8e19fec0f022c26d04
Refname:    refs/heads/master
Author:     Josh Poimboeuf <[email protected]>
AuthorDate: Thu Feb 8 17:09:25 2018 -0600
Committer:  Ingo Molnar <[email protected]>
CommitDate: Thu Feb 15 01:15:49 2018 +0100

    objtool: Fix segfault in ignore_unreachable_insn()
    
    Peter Zijlstra's patch for converting WARN() to use UD2 triggered a
    bunch of false "unreachable instruction" warnings, which then triggered
    a seg fault in ignore_unreachable_insn().
    
    The seg fault happened when it tried to dereference a NULL 'insn->func'
    pointer.  Thanks to static_cpu_has(), some functions can jump to a
    non-function area in the .altinstr_aux section.  That breaks
    ignore_unreachable_insn()'s assumption that it's always inside the
    original function.
    
    Make sure ignore_unreachable_insn() only follows jumps within the
    current function.
    
    Reported-by: Borislav Petkov <[email protected]>
    Signed-off-by: Josh Poimboeuf <[email protected]>
    Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
    Cc: Andy Lutomirski <[email protected]>
    Cc: Arjan van de Ven <[email protected]>
    Cc: Brian Gerst <[email protected]>
    Cc: Denys Vlasenko <[email protected]>
    Cc: H. Peter Anvin <[email protected]>
    Cc: Linus Torvalds <[email protected]>
    Cc: Peter Zijlstra <[email protected]>
    Cc: Thomas Gleixner <[email protected]>
    Cc: kbuild test robot <[email protected]>
    Link: http://lkml.kernel.org/r/bace77a60d5af9b45eddb8f8fb9c776c8de657ef.1518130694.git.jpoimboe@redhat.com
    Signed-off-by: Ingo Molnar <[email protected]>
---
 tools/objtool/check.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 2e458eb45586..c7fb5c2392ee 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1935,13 +1935,19 @@ static bool ignore_unreachable_insn(struct instruction *insn)
 		if (is_kasan_insn(insn) || is_ubsan_insn(insn))
 			return true;
 
-		if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest) {
-			insn = insn->jump_dest;
-			continue;
+		if (insn->type == INSN_JUMP_UNCONDITIONAL) {
+			if (insn->jump_dest &&
+			    insn->jump_dest->func == insn->func) {
+				insn = insn->jump_dest;
+				continue;
+			}
+
+			break;
 		}
 
 		if (insn->offset + insn->len >= insn->func->offset + insn->func->len)
 			break;
+
 		insn = list_next_entry(insn, list);
 	}
 
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html