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: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 25 Feb 2019 13:43:34 +0100
From:   Peter Zijlstra <peterz@...radead.org>
To:     torvalds@...ux-foundation.org, tglx@...utronix.de, hpa@...or.com,
        julien.thierry@....com, will.deacon@....com, luto@...capital.net,
        mingo@...nel.org, catalin.marinas@....com, james.morse@....com,
        valentin.schneider@....com, brgerst@...il.com, jpoimboe@...hat.com,
        luto@...nel.org, bp@...en8.de, dvlasenk@...hat.com
Cc:     linux-kernel@...r.kernel.org, peterz@...radead.org
Subject: [PATCH 4/6] objtool: Replace STACK_FRAME_NON_STANDARD annotation

Replace the existing STACK_FRAME_NON_STANDARD annotation with a
'better' scheme.

The old annotation works by taking the address of a function; this
is visible to the compiler and might affect code generation (the
function pointer escapes). The new annotation simply stores the
function name and has objtool do a symtab lookup.

Signed-off-by: Peter Zijlstra (Intel) <peterz@...radead.org>
---
 include/linux/frame.h |   19 +++++++++++++---
 tools/objtool/check.c |   58 +++++++++++++++++++++-----------------------------
 tools/objtool/check.h |    1 
 3 files changed, 41 insertions(+), 37 deletions(-)

--- a/include/linux/frame.h
+++ b/include/linux/frame.h
@@ -11,9 +11,22 @@
  *
  * For more information, see tools/objtool/Documentation/stack-validation.txt.
  */
-#define STACK_FRAME_NON_STANDARD(func) \
-	static void __used __section(.discard.func_stack_frame_non_standard) \
-		*__func_stack_frame_non_standard_##func = func
+#define STACK_FRAME_NON_STANDARD(func)					\
+	asm (".pushsection .discard.nonstd_frame_strtab, \"S\", @3\n\t"	\
+	     "999: .ascii \"" #func "\"\n\t"				\
+	     "     .byte 0\n\t"						\
+	     ".popsection\n\t"						\
+	     ".pushsection .discard.nonstd_frame\n\t"			\
+	     ".long 999b - .\n\t"					\
+	     ".popsection\n\t")
+
+/*
+ * SHT_STRTAB(@3) sections should start with a \0 byte such that the 0 offset
+ * encodes the NULL string.
+ */
+asm (".pushsection .discard.nonstd_frame_strtab, \"S\", @3\n\t"
+     ".byte 0\n\t"
+     ".popsection\n\t");
 
 #else /* !CONFIG_STACK_VALIDATION */
 
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -105,29 +105,6 @@ static struct instruction *next_insn_sam
 	     insn = next_insn_same_sec(file, insn))
 
 /*
- * Check if the function has been manually whitelisted with the
- * STACK_FRAME_NON_STANDARD macro, or if it should be automatically whitelisted
- * due to its use of a context switching instruction.
- */
-static bool ignore_func(struct objtool_file *file, struct symbol *func)
-{
-	struct rela *rela;
-
-	/* check for STACK_FRAME_NON_STANDARD */
-	if (file->whitelist && file->whitelist->rela)
-		list_for_each_entry(rela, &file->whitelist->rela->rela_list, list) {
-			if (rela->sym->type == STT_SECTION &&
-			    rela->sym->sec == func->sec &&
-			    rela->addend == func->offset)
-				return true;
-			if (rela->sym->type == STT_FUNC && rela->sym == func)
-				return true;
-		}
-
-	return false;
-}
-
-/*
  * This checks to see if the given function is a "noreturn" function.
  *
  * For global functions which are outside the scope of this object file, we
@@ -434,21 +411,37 @@ static int add_dead_ends(struct objtool_
 static void add_ignores(struct objtool_file *file)
 {
 	struct instruction *insn;
-	struct section *sec;
+	struct section *strtab_sec, *sec;
 	struct symbol *func;
+	struct rela *rela;
+	const char *name;
 
-	for_each_sec(file, sec) {
-		list_for_each_entry(func, &sec->symbol_list, list) {
-			if (func->type != STT_FUNC)
-				continue;
+	sec = find_section_by_name(file->elf, ".rela.discard.nonstd_frame");
+	if (!sec)
+		return;
 
-			if (!ignore_func(file, func))
-				continue;
+	strtab_sec = find_section_by_name(file->elf, ".discard.nonstd_frame_strtab");
+	if (!strtab_sec) {
+		WARN("missing nonstd_frame strtab");
+		return;
+	}
 
-			func_for_each_insn_all(file, func, insn)
-				insn->ignore = true;
+	list_for_each_entry(rela, &sec->rela_list, list) {
+		if (rela->sym->type != STT_SECTION) {
+			WARN("unexpected relocation symbol type in %s", sec->name);
+			return;
 		}
+
+		name = elf_strptr(file->elf->elf, strtab_sec->idx, rela->addend);
+		func = find_symbol_by_name(file->elf, name);
+		if (!func)
+			continue;
+
+		func_for_each_insn_all(file, func, insn)
+			insn->ignore = true;
 	}
+
+	return;
 }
 
 /*
@@ -2198,7 +2191,6 @@ int check(const char *_objname, bool orc
 
 	INIT_LIST_HEAD(&file.insn_list);
 	hash_init(file.insn_hash);
-	file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard");
 	file.c_file = find_section_by_name(file.elf, ".comment");
 	file.ignore_unreachables = no_unreachable;
 	file.hints = false;
--- a/tools/objtool/check.h
+++ b/tools/objtool/check.h
@@ -60,7 +60,6 @@ struct objtool_file {
 	struct elf *elf;
 	struct list_head insn_list;
 	DECLARE_HASHTABLE(insn_hash, 16);
-	struct section *whitelist;
 	bool ignore_unreachables, c_file, hints, rodata;
 };
 


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ