lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 03 Mar 2022 12:23:58 +0100
From:   Peter Zijlstra <peterz@...radead.org>
To:     x86@...nel.org, joao@...rdrivepizza.com, hjl.tools@...il.com,
        jpoimboe@...hat.com, andrew.cooper3@...rix.com
Cc:     linux-kernel@...r.kernel.org, peterz@...radead.org,
        ndesaulniers@...gle.com, keescook@...omium.org,
        samitolvanen@...gle.com, mark.rutland@....com,
        alyssa.milburn@...el.com, mbenes@...e.cz, rostedt@...dmis.org,
        mhiramat@...nel.org, alexei.starovoitov@...il.com
Subject: [PATCH v3 37/39] objtool: Optionally WARN about unused ANNOTATE_NOENDBR

Separate option because this option is somewhat prone to false
positives since a bunch of symbols/annotations are not correctly
#ifdef'ed, presumably to avoid clutter.

Can be manually ran on allmodconfig builds using OBJTOOL_ARGS.

Signed-off-by: Peter Zijlstra (Intel) <peterz@...radead.org>
---
 tools/objtool/builtin-check.c           |    3 +-
 tools/objtool/check.c                   |   45 +++++++++++++++++++++++++++++---
 tools/objtool/include/objtool/builtin.h |    2 -
 tools/objtool/include/objtool/check.h   |    3 +-
 4 files changed, 46 insertions(+), 7 deletions(-)

--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -21,7 +21,7 @@
 
 bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats,
      lto, vmlinux, mcount, noinstr, backup, sls, dryrun,
-     ibt;
+     ibt, ibt_warn;
 
 static const char * const check_usage[] = {
 	"objtool check [<options>] file.o",
@@ -49,6 +49,7 @@ const struct option check_options[] = {
 	OPT_BOOLEAN('S', "sls", &sls, "validate straight-line-speculation"),
 	OPT_BOOLEAN(0, "dry-run", &dryrun, "don't write the modifications"),
 	OPT_BOOLEAN(0, "ibt", &ibt, "validate ENDBR placement"),
+	OPT_BOOLEAN(0, "ibt-warn", &ibt_warn, "warn about unused ANNOTATE_ENDBR"),
 	OPT_END(),
 };
 
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1814,6 +1814,19 @@ static void set_func_state(struct cfi_st
 	state->stack_size = initial_func_cfi.cfa.offset;
 }
 
+static bool insn_is_endbr(struct instruction *insn)
+{
+	if (insn->type == INSN_ENDBR)
+		return true;
+
+	if (insn->noendbr) {
+		insn->noendbr_hit = 1;
+		return true;
+	}
+
+	return false;
+}
+
 static int read_unwind_hints(struct objtool_file *file)
 {
 	struct cfi_state cfi = init_cfi;
@@ -1860,8 +1873,7 @@ static int read_unwind_hints(struct objt
 		if (ibt && hint->type == UNWIND_HINT_TYPE_REGS_PARTIAL) {
 			struct symbol *sym = find_symbol_by_offset(insn->sec, insn->offset);
 
-			if (sym && sym->bind == STB_GLOBAL &&
-			    insn->type != INSN_ENDBR && !insn->noendbr) {
+			if (sym && sym->bind == STB_GLOBAL && !insn_is_endbr(insn)) {
 				WARN_FUNC("UNWIND_HINT_IRET_REGS without ENDBR",
 					  insn->sec, insn->offset);
 			}
@@ -3146,7 +3158,7 @@ static void validate_ibt_dest(struct obj
 		return;
 	}
 
-	if (dest->noendbr)
+	if (insn_is_endbr(dest))
 		return;
 
 	warn_noendbr("", insn->sec, insn->offset, dest);
@@ -3687,7 +3699,7 @@ static int validate_ibt(struct objtool_f
 			struct instruction *dest;
 
 			dest = validate_ibt_reloc(file, reloc);
-			if (is_data && dest && !dest->noendbr) {
+			if (is_data && dest && !insn_is_endbr(dest)) {
 				warn_noendbr("data ", reloc->sym->sec,
 					     reloc->sym->offset + reloc->addend,
 					     dest);
@@ -3695,6 +3707,31 @@ static int validate_ibt(struct objtool_f
 		}
 	}
 
+	if (ibt_warn) {
+		struct symbol *hypercall_page = find_symbol_by_name(file->elf, "hypercall_page");
+		struct instruction *insn;
+
+		for_each_insn(file, insn) {
+			if (!insn->noendbr || insn->noendbr_hit)
+				continue;
+
+			if (hypercall_page) {
+				/*
+				 * The Xen hypercall page contains many
+				 * hypercalls (and unused slots) that are never
+				 * indirectly called. Still every slot has an
+				 * annotation. Suppress complaints.
+				 */
+				if (insn->sec == hypercall_page->sec &&
+				    insn->offset >= hypercall_page->offset &&
+				    insn->offset <  hypercall_page->offset + hypercall_page->len)
+					continue;
+			}
+
+			WARN_FUNC("unused ANNOTATE_NOENDBR", insn->sec, insn->offset);
+		}
+	}
+
 	return 0;
 }
 
--- a/tools/objtool/include/objtool/builtin.h
+++ b/tools/objtool/include/objtool/builtin.h
@@ -10,7 +10,7 @@
 extern const struct option check_options[];
 extern bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats,
 	    lto, vmlinux, mcount, noinstr, backup, sls, dryrun,
-	    ibt;
+	    ibt, ibt_warn;
 
 extern int cmd_parse_options(int argc, const char **argv, const char * const usage[]);
 
--- a/tools/objtool/include/objtool/check.h
+++ b/tools/objtool/include/objtool/check.h
@@ -51,7 +51,8 @@ struct instruction {
 	   ignore_alts	: 1,
 	   hint		: 1,
 	   retpoline_safe : 1,
-	   noendbr	: 1;
+	   noendbr	: 1,
+	   noendbr_hit  : 1;
 		/* 2 bit hole */
 	s8 instr;
 	u8 visited;


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ