Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5007453c authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Greg Kroah-Hartman
Browse files

x86/ia32: Fix ia32_restore_sigcontext() AC leak



[ Upstream commit 67a0514afdbb8b2fc70b771b8c77661a9cb9d3a9 ]

Objtool spotted that we call native_load_gs_index() with AC set.
Re-arrange the code to avoid that.

Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
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>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 4614b0bb
Loading
Loading
Loading
Loading
+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();