From: Peter Zijlstra <peterz@infradead.org>
To: tglx@linutronix.de, jpoimboe@redhat.com
Cc: linux-kernel@vger.kernel.org, x86@kernel.org,
peterz@infradead.org, mhiramat@kernel.org, mbenes@suse.cz
Subject: [PATCH v4 08/13] objtool: Detect loading function pointers across noinstr
Date: Wed, 25 Mar 2020 18:45:33 +0100 [thread overview]
Message-ID: <20200325174605.959837022@infradead.org> (raw)
In-Reply-To: 20200325174525.772641599@infradead.org
Detect if noinstr text loads functions pointers from regular text,
doing so is a definite sign that indirect function calls are unsafe.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
tools/objtool/arch.h | 2 +
tools/objtool/check.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++
tools/objtool/check.h | 2 -
3 files changed, 74 insertions(+), 1 deletion(-)
--- a/tools/objtool/arch.h
+++ b/tools/objtool/arch.h
@@ -75,4 +75,6 @@ int arch_decode_instruction(struct elf *
bool arch_callee_saved_reg(unsigned char reg);
+#define MAX_INSN_SIZE 15
+
#endif /* _ARCH_H */
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -42,6 +42,25 @@ struct instruction *find_insn(struct obj
return NULL;
}
+static struct instruction *find_insn_containing(struct objtool_file *file, struct section *sec,
+ unsigned long offset)
+{
+ struct instruction *insn;
+ unsigned long o;
+
+ for_offset_range(o, offset - MAX_INSN_SIZE - 1, offset) {
+ hash_for_each_possible(file->insn_hash, insn, hash, sec_offset_hash(sec, o)) {
+ if (insn->sec != sec)
+ continue;
+
+ if (insn->offset <= offset && insn->offset + insn->len > offset)
+ return insn;
+ }
+ }
+
+ return NULL;
+}
+
static struct instruction *next_insn_same_sec(struct objtool_file *file,
struct instruction *insn)
{
@@ -2146,6 +2165,32 @@ static int apply_insn_hint(struct objtoo
return 0;
}
+static int validate_rela(struct instruction *insn, struct insn_state *state)
+{
+ /*
+ * Assume that any text rela that's not a CALL or JMP is a load of a
+ * function pointer.
+ */
+
+ switch (insn->type) {
+ case INSN_CALL:
+ case INSN_CALL_DYNAMIC:
+ case INSN_JUMP_CONDITIONAL:
+ case INSN_JUMP_UNCONDITIONAL:
+ return 0;
+
+ default:
+ break;
+ }
+
+ if (state->noinstr && state->instr <= 0 && insn->has_text_rela) {
+ WARN_FUNC("loading non-noinstr function pointer", insn->sec, insn->offset);
+ return 1;
+ }
+
+ return 0;
+}
+
/*
* Follow the branch starting at the given instruction, and recursively follow
* any other branches (jumps). Meanwhile, track the frame pointer state at
@@ -2224,6 +2269,10 @@ static int validate_branch(struct objtoo
return 0;
}
+ ret = validate_rela(insn, &state);
+ if (ret)
+ return ret;
+
switch (insn->type) {
case INSN_RETURN:
@@ -2492,6 +2541,25 @@ static bool ignore_unreachable_insn(stru
return false;
}
+static void prepare_insn_rela(struct objtool_file *file, struct section *sec)
+{
+ struct instruction *insn;
+ struct rela *rela;
+
+ if (!sec->rela)
+ return;
+
+ list_for_each_entry(rela, &sec->rela->rela_list, list) {
+ insn = find_insn_containing(file, sec, rela->offset);
+ if (!insn)
+ continue;
+
+ insn->has_text_rela = rela->sym && rela->sym->sec &&
+ rela->sym->sec->text &&
+ !rela->sym->sec->noinstr;
+ }
+}
+
static int validate_section(struct objtool_file *file, struct section *sec)
{
struct symbol *func;
@@ -2514,6 +2582,9 @@ static int validate_section(struct objto
if (vmlinux)
state.noinstr = sec->noinstr;
+ if (state.noinstr)
+ prepare_insn_rela(file, sec);
+
list_for_each_entry(func, &sec->symbol_list, list) {
if (func->type != STT_FUNC)
continue;
--- a/tools/objtool/check.h
+++ b/tools/objtool/check.h
@@ -31,7 +31,7 @@ struct instruction {
enum insn_type type;
unsigned long immediate;
bool alt_group, dead_end, ignore, hint, save, restore, ignore_alts;
- bool retpoline_safe;
+ bool retpoline_safe, has_text_rela;
s8 instr;
u8 visited;
struct symbol *call_dest;
next prev parent reply other threads:[~2020-03-25 17:48 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-25 17:45 [PATCH v4 00/13] objtool: vmlinux.o and moinstr validation Peter Zijlstra
2020-03-25 17:45 ` [PATCH v4 01/13] objtool: Remove CFI save/restore special case Peter Zijlstra
2020-03-26 11:30 ` Peter Zijlstra
2020-03-26 12:58 ` Peter Zijlstra
2020-03-26 13:44 ` Josh Poimboeuf
2020-03-26 15:38 ` Peter Zijlstra
2020-03-27 4:19 ` Josh Poimboeuf
2020-03-26 14:44 ` Miroslav Benes
2020-03-26 15:04 ` Miroslav Benes
2020-03-26 13:00 ` Peter Zijlstra
2020-03-26 13:56 ` Josh Poimboeuf
2020-03-26 15:49 ` Peter Zijlstra
2020-03-26 19:57 ` Peter Zijlstra
2020-03-27 1:00 ` Josh Poimboeuf
2020-03-30 17:02 ` Peter Zijlstra
2020-03-30 19:02 ` Josh Poimboeuf
2020-03-30 20:02 ` Peter Zijlstra
2020-03-30 20:29 ` Peter Zijlstra
2020-03-31 11:16 ` [RFC][PATCH] objtool,ftrace: Implement UNWIND_HINT_RET_OFFSET Peter Zijlstra
2020-03-31 15:31 ` Steven Rostedt
2020-03-31 16:06 ` [RFC][PATCH] x86,ftrace: Shrink ftrace_regs_caller() by one byte Peter Zijlstra
2020-03-31 19:58 ` [RFC][PATCH] objtool,ftrace: Implement UNWIND_HINT_RET_OFFSET Peter Zijlstra
2020-03-31 20:26 ` Josh Poimboeuf
2020-03-31 20:23 ` Josh Poimboeuf
2020-03-31 20:40 ` Peter Zijlstra
2020-03-31 21:07 ` Peter Zijlstra
2020-03-31 21:17 ` Josh Poimboeuf
2020-03-31 21:20 ` Josh Poimboeuf
2020-03-31 22:27 ` [PATCH v2] " Peter Zijlstra
2020-04-01 14:14 ` Josh Poimboeuf
2020-04-01 14:22 ` Peter Zijlstra
2020-04-01 14:39 ` Josh Poimboeuf
2020-04-01 15:38 ` Peter Zijlstra
2020-04-01 15:39 ` Steven Rostedt
2020-04-01 15:43 ` Julien Thierry
2020-04-01 17:09 ` Peter Zijlstra
2020-04-01 17:33 ` Steven Rostedt
2020-04-01 17:45 ` Peter Zijlstra
2020-04-01 18:20 ` Steven Rostedt
2020-04-01 20:20 ` Peter Zijlstra
2020-04-01 17:37 ` Josh Poimboeuf
2020-04-02 6:41 ` Julien Thierry
2020-04-02 6:56 ` Julien Thierry
2020-04-02 7:50 ` Peter Zijlstra
2020-04-02 8:16 ` Julien Thierry
2020-04-02 8:17 ` Peter Zijlstra
2020-04-02 8:29 ` Julien Thierry
2020-04-02 8:58 ` Miroslav Benes
2020-03-25 17:45 ` [PATCH v4 02/13] objtool: Factor out CFI hints Peter Zijlstra
2020-03-25 18:26 ` Miroslav Benes
2020-03-25 19:41 ` Peter Zijlstra
2020-03-25 17:45 ` [PATCH v4 03/13] objtool: Rename struct cfi_state Peter Zijlstra
2020-03-25 17:45 ` [PATCH v4 04/13] objtool: Fix !CFI insn_state propagation Peter Zijlstra
2020-03-25 17:45 ` [PATCH v4 05/13] objtool: Implement noinstr validation Peter Zijlstra
2020-03-25 17:45 ` [PATCH v4 06/13] objtool: Optimize !vmlinux.o again Peter Zijlstra
2020-03-25 17:45 ` [PATCH v4 07/13] objtool: Use sec_offset_hash() for insn_hash Peter Zijlstra
2020-03-25 17:45 ` Peter Zijlstra [this message]
2020-03-25 17:45 ` [PATCH v4 09/13] kbuild/objtool: Add objtool-vmlinux.o pass Peter Zijlstra
2020-03-25 17:45 ` [PATCH v4 10/13] objtool: Avoid iterating !text section symbols Peter Zijlstra
2020-03-25 17:45 ` [PATCH v4 11/13] objtool: Rearrange validate_section() Peter Zijlstra
2020-03-25 17:45 ` [PATCH v4 12/13] objtool: Add STT_NOTYPE noinstr validation Peter Zijlstra
2020-03-25 17:45 ` [PATCH v4 13/13] objtool: Also consider .entry.text as noinstr Peter Zijlstra
2020-03-25 19:03 ` [PATCH v4 00/13] objtool: vmlinux.o and moinstr validation Miroslav Benes
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200325174605.959837022@infradead.org \
--to=peterz@infradead.org \
--cc=jpoimboe@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mbenes@suse.cz \
--cc=mhiramat@kernel.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).