Commit 6ec62961 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'core-objtool-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull objtool updates from Ingo Molnar:
 "This is a series from Peter Zijlstra that adds x86 build-time uaccess
  validation of SMAP to objtool, which will detect and warn about the
  following uaccess API usage bugs and weirdnesses:

   - call to %s() with UACCESS enabled
   - return with UACCESS enabled
   - return with UACCESS disabled from a UACCESS-safe function
   - recursive UACCESS enable
   - redundant UACCESS disable
   - UACCESS-safe disables UACCESS

  As it turns out not leaking uaccess permissions outside the intended
  uaccess functionality is hard when the interfaces are complex and when
  such bugs are mostly dormant.

  As a bonus we now also check the DF flag. We had at least one
  high-profile bug in that area in the early days of Linux, and the
  checking is fairly simple. The checks performed and warnings emitted
  are:

   - call to %s() with DF set
   - return with DF set
   - return with modified stack frame
   - recursive STD
   - redundant CLD

  It's all x86-only for now, but later on this can also be used for PAN
  on ARM and objtool is fairly cross-platform in principle.

  While all warnings emitted by this new checking facility that got
  reported to us were fixed, there might be GCC version dependent
  warnings that were not reported yet - which we'll address, should they
  trigger.

  The warnings are non-fatal build warnings"

* 'core-objtool-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (27 commits)
  mm/uaccess: Use 'unsigned long' to placate UBSAN warnings on older GCC versions
  x86/uaccess: Dont leak the AC flag into __put_user() argument evaluation
  sched/x86_64: Don't save flags on context switch
  objtool: Add Direction Flag validation
  objtool: Add UACCESS validation
  objtool: Fix sibling call detection
  objtool: Rewrite alt->skip_orig
  objtool: Add --backtrace support
  objtool: Rewrite add_ignores()
  objtool: Handle function aliases
  objtool: Set insn->func for alternatives
  x86/uaccess, kcov: Disable stack protector
  x86/uaccess, ftrace: Fix ftrace_likely_update() vs. SMAP
  x86/uaccess, ubsan: Fix UBSAN vs. SMAP
  x86/uaccess, kasan: Fix KASAN vs SMAP
  x86/smap: Ditch __stringify()
  x86/uaccess: Introduce user_access_{save,restore}()
  x86/uaccess, signal: Fix AC=1 bloat
  x86/uaccess: Always inline user_access_begin()
  x86/uaccess, xen: Suppress SMAP warnings
  ...
parents 171c2bcb 29da93fe
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -650,6 +650,7 @@ ENTRY(__switch_to_asm)
	pushl	%ebx
	pushl	%edi
	pushl	%esi
	pushfl

	/* switch stack */
	movl	%esp, TASK_threadsp(%eax)
@@ -672,6 +673,7 @@ ENTRY(__switch_to_asm)
#endif

	/* restore callee-saved registers */
	popfl
	popl	%esi
	popl	%edi
	popl	%ebx
+17 −12
Original line number Diff line number Diff line
@@ -61,9 +61,8 @@
} while (0)

#define RELOAD_SEG(seg)		{		\
	unsigned int pre = GET_SEG(seg);	\
	unsigned int pre = (seg) | 3;		\
	unsigned int cur = get_user_seg(seg);	\
	pre |= 3;				\
	if (pre != cur)				\
		set_user_seg(seg, pre);		\
}
@@ -72,6 +71,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
				   struct sigcontext_32 __user *sc)
{
	unsigned int tmpflags, err = 0;
	u16 gs, fs, es, ds;
	void __user *buf;
	u32 tmp;

@@ -79,16 +79,10 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
	current->restart_block.fn = do_no_restart_syscall;

	get_user_try {
		/*
		 * Reload fs and gs if they have changed in the signal
		 * handler.  This does not handle long fs/gs base changes in
		 * the handler, but does not clobber them at least in the
		 * normal case.
		 */
		RELOAD_SEG(gs);
		RELOAD_SEG(fs);
		RELOAD_SEG(ds);
		RELOAD_SEG(es);
		gs = GET_SEG(gs);
		fs = GET_SEG(fs);
		ds = GET_SEG(ds);
		es = GET_SEG(es);

		COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
		COPY(dx); COPY(cx); COPY(ip); COPY(ax);
@@ -106,6 +100,17 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
		buf = compat_ptr(tmp);
	} get_user_catch(err);

	/*
	 * Reload fs and gs if they have changed in the signal
	 * handler.  This does not handle long fs/gs base changes in
	 * the handler, but does not clobber them at least in the
	 * normal case.
	 */
	RELOAD_SEG(gs);
	RELOAD_SEG(fs);
	RELOAD_SEG(ds);
	RELOAD_SEG(es);

	err |= fpu__restore_sig(buf, 1);

	force_iret();
+11 −0
Original line number Diff line number Diff line
@@ -19,6 +19,17 @@
	.endm
#endif

/*
 * objtool annotation to ignore the alternatives and only consider the original
 * instruction(s).
 */
.macro ANNOTATE_IGNORE_ALTERNATIVE
	.Lannotate_\@:
	.pushsection .discard.ignore_alts
	.long .Lannotate_\@ - .
	.popsection
.endm

/*
 * Issue one struct alt_instr descriptor entry (need to put it into
 * the section .altinstructions, see below). This entry contains
+10 −0
Original line number Diff line number Diff line
@@ -45,6 +45,16 @@
#define LOCK_PREFIX ""
#endif

/*
 * objtool annotation to ignore the alternatives and only consider the original
 * instruction(s).
 */
#define ANNOTATE_IGNORE_ALTERNATIVE				\
	"999:\n\t"						\
	".pushsection .discard.ignore_alts\n\t"			\
	".long 999b - .\n\t"					\
	".popsection\n\t"

struct alt_instr {
	s32 instr_offset;	/* original instruction */
	s32 repl_offset;	/* offset to replacement instruction */
+0 −24
Original line number Diff line number Diff line
@@ -148,30 +148,6 @@
	_ASM_PTR (entry);					\
	.popsection

.macro ALIGN_DESTINATION
	/* check for bad alignment of destination */
	movl %edi,%ecx
	andl $7,%ecx
	jz 102f				/* already aligned */
	subl $8,%ecx
	negl %ecx
	subl %ecx,%edx
100:	movb (%rsi),%al
101:	movb %al,(%rdi)
	incq %rsi
	incq %rdi
	decl %ecx
	jnz 100b
102:
	.section .fixup,"ax"
103:	addl %ecx,%edx			/* ecx is zerorest also */
	jmp copy_user_handle_tail
	.previous

	_ASM_EXTABLE_UA(100b, 103b)
	_ASM_EXTABLE_UA(101b, 103b)
	.endm

#else
# define _EXPAND_EXTABLE_HANDLE(x) #x
# define _ASM_EXTABLE_HANDLE(from, to, handler)			\
Loading