Commit 47058bb5 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Al Viro
Browse files

x86: remove address space overrides using set_fs()



Stop providing the possibility to override the address space using
set_fs() now that there is no need for that any more.  To properly
handle the TASK_SIZE_MAX checking for 4 vs 5-level page tables on
x86 a new alternative is introduced, which just like the one in
entry_64.S has to use the hardcoded virtual address bits to escape
the fact that TASK_SIZE_MAX isn't actually a constant when 5-level
page tables are enabled.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent a1d826d4
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -237,7 +237,6 @@ config X86
	select HAVE_ARCH_KCSAN			if X86_64
	select X86_FEATURE_NAMES		if PROC_FS
	select PROC_PID_ARCH_STATUS		if PROC_FS
	select SET_FS
	imply IMA_SECURE_AND_OR_TRUSTED_BOOT    if EFI

config INSTRUCTION_DECODER
+0 −1
Original line number Diff line number Diff line
@@ -239,7 +239,6 @@ beyond_if:
	(regs)->ss = __USER32_DS;
	regs->r8 = regs->r9 = regs->r10 = regs->r11 =
	regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0;
	set_fs(USER_DS);
	return 0;
}

+1 −10
Original line number Diff line number Diff line
@@ -482,10 +482,6 @@ extern unsigned int fpu_user_xstate_size;

struct perf_event;

typedef struct {
	unsigned long		seg;
} mm_segment_t;

struct thread_struct {
	/* Cached TLS descriptors: */
	struct desc_struct	tls_array[GDT_ENTRY_TLS_ENTRIES];
@@ -538,8 +534,6 @@ struct thread_struct {
	 */
	unsigned long		iopl_emul;

	mm_segment_t		addr_limit;

	unsigned int		sig_on_uaccess_err:1;

	/* Floating point and extended processor state */
@@ -785,15 +779,12 @@ static inline void spin_lock_prefetch(const void *x)
#define INIT_THREAD  {							  \
	.sp0			= TOP_OF_INIT_STACK,			  \
	.sysenter_cs		= __KERNEL_CS,				  \
	.addr_limit		= KERNEL_DS,				  \
}

#define KSTK_ESP(task)		(task_pt_regs(task)->sp)

#else
#define INIT_THREAD  {						\
	.addr_limit		= KERNEL_DS,			\
}
#define INIT_THREAD { }

extern unsigned long KSTK_ESP(struct task_struct *task);

+0 −2
Original line number Diff line number Diff line
@@ -102,7 +102,6 @@ struct thread_info {
#define TIF_SYSCALL_TRACEPOINT	28	/* syscall tracepoint instrumentation */
#define TIF_ADDR32		29	/* 32-bit address space on 64 bits */
#define TIF_X32			30	/* 32-bit native x86-64 binary */
#define TIF_FSCHECK		31	/* Check FS is USER_DS on return */

#define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
@@ -131,7 +130,6 @@ struct thread_info {
#define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_ADDR32		(1 << TIF_ADDR32)
#define _TIF_X32		(1 << TIF_X32)
#define _TIF_FSCHECK		(1 << TIF_FSCHECK)

/* flags to check in __switch_to() */
#define _TIF_WORK_CTXSW_BASE					\
+1 −25
Original line number Diff line number Diff line
@@ -12,30 +12,6 @@
#include <asm/smap.h>
#include <asm/extable.h>

/*
 * The fs value determines whether argument validity checking should be
 * performed or not.  If get_fs() == USER_DS, checking is performed, with
 * get_fs() == KERNEL_DS, checking is bypassed.
 *
 * For historical reasons, these macros are grossly misnamed.
 */

#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })

#define KERNEL_DS	MAKE_MM_SEG(-1UL)
#define USER_DS 	MAKE_MM_SEG(TASK_SIZE_MAX)

#define get_fs()	(current->thread.addr_limit)
static inline void set_fs(mm_segment_t fs)
{
	current->thread.addr_limit = fs;
	/* On user-mode return, check fs is correct */
	set_thread_flag(TIF_FSCHECK);
}

#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
#define user_addr_max() (current->thread.addr_limit.seg)

/*
 * Test whether a block of memory is a valid user space address.
 * Returns 0 if the range is valid, nonzero otherwise.
@@ -93,7 +69,7 @@ static inline bool pagefault_disabled(void);
#define access_ok(addr, size)					\
({									\
	WARN_ON_IN_IRQ();						\
	likely(!__range_not_ok(addr, size, user_addr_max()));		\
	likely(!__range_not_ok(addr, size, TASK_SIZE_MAX));		\
})

/*
Loading