Commit ea24213d authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

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: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: default avatarJosh 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: default avatarIngo Molnar <mingo@kernel.org>
parent 54262aa2
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -222,6 +222,9 @@ endif
ifdef CONFIG_RETPOLINE
  objtool_args += --retpoline
endif
ifdef CONFIG_X86_SMAP
  objtool_args += --uaccess
endif

# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
+5 −1
Original line number Diff line number Diff line
@@ -33,7 +33,9 @@
#define INSN_STACK		8
#define INSN_BUG		9
#define INSN_NOP		10
#define INSN_OTHER		11
#define INSN_STAC		11
#define INSN_CLAC		12
#define INSN_OTHER		13
#define INSN_LAST		INSN_OTHER

enum op_dest_type {
@@ -41,6 +43,7 @@ enum op_dest_type {
	OP_DEST_REG_INDIRECT,
	OP_DEST_MEM,
	OP_DEST_PUSH,
	OP_DEST_PUSHF,
	OP_DEST_LEAVE,
};

@@ -55,6 +58,7 @@ enum op_src_type {
	OP_SRC_REG_INDIRECT,
	OP_SRC_CONST,
	OP_SRC_POP,
	OP_SRC_POPF,
	OP_SRC_ADD,
	OP_SRC_AND,
};
+10 −3
Original line number Diff line number Diff line
@@ -357,19 +357,26 @@ int arch_decode_instruction(struct elf *elf, struct section *sec,
		/* pushf */
		*type = INSN_STACK;
		op->src.type = OP_SRC_CONST;
		op->dest.type = OP_DEST_PUSH;
		op->dest.type = OP_DEST_PUSHF;
		break;

	case 0x9d:
		/* popf */
		*type = INSN_STACK;
		op->src.type = OP_SRC_POP;
		op->src.type = OP_SRC_POPF;
		op->dest.type = OP_DEST_MEM;
		break;

	case 0x0f:

		if (op2 >= 0x80 && op2 <= 0x8f) {
		if (op2 == 0x01) {

			if (modrm == 0xca)
				*type = INSN_CLAC;
			else if (modrm == 0xcb)
				*type = INSN_STAC;

		} else if (op2 >= 0x80 && op2 <= 0x8f) {

			*type = INSN_JUMP_CONDITIONAL;

+2 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@
#include "builtin.h"
#include "check.h"

bool no_fp, no_unreachable, retpoline, module, backtrace;
bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess;

static const char * const check_usage[] = {
	"objtool check [<options>] file.o",
@@ -42,6 +42,7 @@ const struct option check_options[] = {
	OPT_BOOLEAN('r', "retpoline", &retpoline, "Validate retpoline assumptions"),
	OPT_BOOLEAN('m', "module", &module, "Indicates the object will be part of a kernel module"),
	OPT_BOOLEAN('b', "backtrace", &backtrace, "unwind on error"),
	OPT_BOOLEAN('a', "uaccess", &uaccess, "enable uaccess checking"),
	OPT_END(),
};

+1 −1
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@
#include <subcmd/parse-options.h>

extern const struct option check_options[];
extern bool no_fp, no_unreachable, retpoline, module, backtrace;
extern bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess;

extern int cmd_check(int argc, const char **argv);
extern int cmd_orc(int argc, const char **argv);
Loading