objtool: Add UACCESS validation
It is important that UACCESS regions are as small as possible; furthermore the UACCESS state is not scheduled, so doing anything that might directly call into the scheduler will cause random code to be ran with UACCESS enabled. Teach objtool too track UACCESS state and warn about any CALL made while UACCESS is enabled. This very much includes the __fentry__() and __preempt_schedule() calls. Note that exceptions _do_ save/restore the UACCESS state, and therefore they can drive preemption. This also means that all exception handlers must have an otherwise redundant UACCESS disable instruction; therefore ignore this warning for !STT_FUNC code (exception handlers are not normal functions). Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:

committed by
Ingo Molnar

parent
54262aa283
commit
ea24213d80
@@ -23,6 +23,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "builtin.h"
|
||||
#include "special.h"
|
||||
#include "warn.h"
|
||||
|
||||
@@ -42,6 +43,7 @@
|
||||
#define ALT_NEW_LEN_OFFSET 11
|
||||
|
||||
#define X86_FEATURE_POPCNT (4*32+23)
|
||||
#define X86_FEATURE_SMAP (9*32+20)
|
||||
|
||||
struct special_entry {
|
||||
const char *sec;
|
||||
@@ -110,6 +112,22 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry,
|
||||
*/
|
||||
if (feature == X86_FEATURE_POPCNT)
|
||||
alt->skip_orig = true;
|
||||
|
||||
/*
|
||||
* If UACCESS validation is enabled; force that alternative;
|
||||
* otherwise force it the other way.
|
||||
*
|
||||
* What we want to avoid is having both the original and the
|
||||
* alternative code flow at the same time, in that case we can
|
||||
* find paths that see the STAC but take the NOP instead of
|
||||
* CLAC and the other way around.
|
||||
*/
|
||||
if (feature == X86_FEATURE_SMAP) {
|
||||
if (uaccess)
|
||||
alt->skip_orig = true;
|
||||
else
|
||||
alt->skip_alt = true;
|
||||
}
|
||||
}
|
||||
|
||||
orig_rela = find_rela_by_dest(sec, offset + entry->orig);
|
||||
|
Reference in New Issue
Block a user