Skip to content

Commit 47058bb

Browse files
Christoph HellwigAl Viro
authored andcommitted
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: Christoph Hellwig <hch@lst.de> Reviewed-by: Kees Cook <keescook@chromium.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent a1d826d commit 47058bb

8 files changed

Lines changed: 39 additions & 77 deletions

File tree

arch/x86/Kconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,6 @@ config X86
237237
select HAVE_ARCH_KCSAN if X86_64
238238
select X86_FEATURE_NAMES if PROC_FS
239239
select PROC_PID_ARCH_STATUS if PROC_FS
240-
select SET_FS
241240
imply IMA_SECURE_AND_OR_TRUSTED_BOOT if EFI
242241

243242
config INSTRUCTION_DECODER

arch/x86/ia32/ia32_aout.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,6 @@ static int load_aout_binary(struct linux_binprm *bprm)
239239
(regs)->ss = __USER32_DS;
240240
regs->r8 = regs->r9 = regs->r10 = regs->r11 =
241241
regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0;
242-
set_fs(USER_DS);
243242
return 0;
244243
}
245244

arch/x86/include/asm/processor.h

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -482,10 +482,6 @@ extern unsigned int fpu_user_xstate_size;
482482

483483
struct perf_event;
484484

485-
typedef struct {
486-
unsigned long seg;
487-
} mm_segment_t;
488-
489485
struct thread_struct {
490486
/* Cached TLS descriptors: */
491487
struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
@@ -538,8 +534,6 @@ struct thread_struct {
538534
*/
539535
unsigned long iopl_emul;
540536

541-
mm_segment_t addr_limit;
542-
543537
unsigned int sig_on_uaccess_err:1;
544538

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

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

793786
#else
794-
#define INIT_THREAD { \
795-
.addr_limit = KERNEL_DS, \
796-
}
787+
#define INIT_THREAD { }
797788

798789
extern unsigned long KSTK_ESP(struct task_struct *task);
799790

arch/x86/include/asm/thread_info.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ struct thread_info {
102102
#define TIF_SYSCALL_TRACEPOINT 28 /* syscall tracepoint instrumentation */
103103
#define TIF_ADDR32 29 /* 32-bit address space on 64 bits */
104104
#define TIF_X32 30 /* 32-bit native x86-64 binary */
105-
#define TIF_FSCHECK 31 /* Check FS is USER_DS on return */
106105

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

136134
/* flags to check in __switch_to() */
137135
#define _TIF_WORK_CTXSW_BASE \

arch/x86/include/asm/uaccess.h

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,6 @@
1212
#include <asm/smap.h>
1313
#include <asm/extable.h>
1414

15-
/*
16-
* The fs value determines whether argument validity checking should be
17-
* performed or not. If get_fs() == USER_DS, checking is performed, with
18-
* get_fs() == KERNEL_DS, checking is bypassed.
19-
*
20-
* For historical reasons, these macros are grossly misnamed.
21-
*/
22-
23-
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
24-
25-
#define KERNEL_DS MAKE_MM_SEG(-1UL)
26-
#define USER_DS MAKE_MM_SEG(TASK_SIZE_MAX)
27-
28-
#define get_fs() (current->thread.addr_limit)
29-
static inline void set_fs(mm_segment_t fs)
30-
{
31-
current->thread.addr_limit = fs;
32-
/* On user-mode return, check fs is correct */
33-
set_thread_flag(TIF_FSCHECK);
34-
}
35-
36-
#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
37-
#define user_addr_max() (current->thread.addr_limit.seg)
38-
3915
/*
4016
* Test whether a block of memory is a valid user space address.
4117
* Returns 0 if the range is valid, nonzero otherwise.
@@ -93,7 +69,7 @@ static inline bool pagefault_disabled(void);
9369
#define access_ok(addr, size) \
9470
({ \
9571
WARN_ON_IN_IRQ(); \
96-
likely(!__range_not_ok(addr, size, user_addr_max())); \
72+
likely(!__range_not_ok(addr, size, TASK_SIZE_MAX)); \
9773
})
9874

9975
/*

arch/x86/kernel/asm-offsets.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ static void __used common(void)
3737
OFFSET(TASK_stack_canary, task_struct, stack_canary);
3838
#endif
3939

40-
BLANK();
41-
OFFSET(TASK_addr_limit, task_struct, thread.addr_limit);
42-
4340
BLANK();
4441
OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
4542

arch/x86/lib/getuser.S

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,19 @@
3535
#include <asm/smap.h>
3636
#include <asm/export.h>
3737

38+
#ifdef CONFIG_X86_5LEVEL
39+
#define LOAD_TASK_SIZE_MINUS_N(n) \
40+
ALTERNATIVE __stringify(mov $((1 << 47) - 4096 - (n)),%rdx), \
41+
__stringify(mov $((1 << 56) - 4096 - (n)),%rdx), X86_FEATURE_LA57
42+
#else
43+
#define LOAD_TASK_SIZE_MINUS_N(n) \
44+
mov $(TASK_SIZE_MAX - (n)),%_ASM_DX
45+
#endif
46+
3847
.text
3948
SYM_FUNC_START(__get_user_1)
40-
mov PER_CPU_VAR(current_task), %_ASM_DX
41-
cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX
49+
LOAD_TASK_SIZE_MINUS_N(0)
50+
cmp %_ASM_DX,%_ASM_AX
4251
jae bad_get_user
4352
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
4453
and %_ASM_DX, %_ASM_AX
@@ -51,31 +60,27 @@ SYM_FUNC_END(__get_user_1)
5160
EXPORT_SYMBOL(__get_user_1)
5261

5362
SYM_FUNC_START(__get_user_2)
54-
add $1,%_ASM_AX
55-
jc bad_get_user
56-
mov PER_CPU_VAR(current_task), %_ASM_DX
57-
cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX
63+
LOAD_TASK_SIZE_MINUS_N(1)
64+
cmp %_ASM_DX,%_ASM_AX
5865
jae bad_get_user
5966
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
6067
and %_ASM_DX, %_ASM_AX
6168
ASM_STAC
62-
2: movzwl -1(%_ASM_AX),%edx
69+
2: movzwl (%_ASM_AX),%edx
6370
xor %eax,%eax
6471
ASM_CLAC
6572
ret
6673
SYM_FUNC_END(__get_user_2)
6774
EXPORT_SYMBOL(__get_user_2)
6875

6976
SYM_FUNC_START(__get_user_4)
70-
add $3,%_ASM_AX
71-
jc bad_get_user
72-
mov PER_CPU_VAR(current_task), %_ASM_DX
73-
cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX
77+
LOAD_TASK_SIZE_MINUS_N(3)
78+
cmp %_ASM_DX,%_ASM_AX
7479
jae bad_get_user
7580
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
7681
and %_ASM_DX, %_ASM_AX
7782
ASM_STAC
78-
3: movl -3(%_ASM_AX),%edx
83+
3: movl (%_ASM_AX),%edx
7984
xor %eax,%eax
8085
ASM_CLAC
8186
ret
@@ -84,29 +89,25 @@ EXPORT_SYMBOL(__get_user_4)
8489

8590
SYM_FUNC_START(__get_user_8)
8691
#ifdef CONFIG_X86_64
87-
add $7,%_ASM_AX
88-
jc bad_get_user
89-
mov PER_CPU_VAR(current_task), %_ASM_DX
90-
cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX
92+
LOAD_TASK_SIZE_MINUS_N(7)
93+
cmp %_ASM_DX,%_ASM_AX
9194
jae bad_get_user
9295
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
9396
and %_ASM_DX, %_ASM_AX
9497
ASM_STAC
95-
4: movq -7(%_ASM_AX),%rdx
98+
4: movq (%_ASM_AX),%rdx
9699
xor %eax,%eax
97100
ASM_CLAC
98101
ret
99102
#else
100-
add $7,%_ASM_AX
101-
jc bad_get_user_8
102-
mov PER_CPU_VAR(current_task), %_ASM_DX
103-
cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX
103+
LOAD_TASK_SIZE_MINUS_N(7)
104+
cmp %_ASM_DX,%_ASM_AX
104105
jae bad_get_user_8
105106
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
106107
and %_ASM_DX, %_ASM_AX
107108
ASM_STAC
108-
4: movl -7(%_ASM_AX),%edx
109-
5: movl -3(%_ASM_AX),%ecx
109+
4: movl (%_ASM_AX),%edx
110+
5: movl 4(%_ASM_AX),%ecx
110111
xor %eax,%eax
111112
ASM_CLAC
112113
ret

arch/x86/lib/putuser.S

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,19 @@
3131
* as they get called from within inline assembly.
3232
*/
3333

34-
#define ENTER mov PER_CPU_VAR(current_task), %_ASM_BX
34+
#ifdef CONFIG_X86_5LEVEL
35+
#define LOAD_TASK_SIZE_MINUS_N(n) \
36+
ALTERNATIVE __stringify(mov $((1 << 47) - 4096 - (n)),%rbx), \
37+
__stringify(mov $((1 << 56) - 4096 - (n)),%rbx), X86_FEATURE_LA57
38+
#else
39+
#define LOAD_TASK_SIZE_MINUS_N(n) \
40+
mov $(TASK_SIZE_MAX - (n)),%_ASM_BX
41+
#endif
3542

3643
.text
3744
SYM_FUNC_START(__put_user_1)
38-
ENTER
39-
cmp TASK_addr_limit(%_ASM_BX),%_ASM_CX
45+
LOAD_TASK_SIZE_MINUS_N(0)
46+
cmp %_ASM_BX,%_ASM_CX
4047
jae .Lbad_put_user
4148
ASM_STAC
4249
1: movb %al,(%_ASM_CX)
@@ -47,9 +54,7 @@ SYM_FUNC_END(__put_user_1)
4754
EXPORT_SYMBOL(__put_user_1)
4855

4956
SYM_FUNC_START(__put_user_2)
50-
ENTER
51-
mov TASK_addr_limit(%_ASM_BX),%_ASM_BX
52-
sub $1,%_ASM_BX
57+
LOAD_TASK_SIZE_MINUS_N(1)
5358
cmp %_ASM_BX,%_ASM_CX
5459
jae .Lbad_put_user
5560
ASM_STAC
@@ -61,9 +66,7 @@ SYM_FUNC_END(__put_user_2)
6166
EXPORT_SYMBOL(__put_user_2)
6267

6368
SYM_FUNC_START(__put_user_4)
64-
ENTER
65-
mov TASK_addr_limit(%_ASM_BX),%_ASM_BX
66-
sub $3,%_ASM_BX
69+
LOAD_TASK_SIZE_MINUS_N(3)
6770
cmp %_ASM_BX,%_ASM_CX
6871
jae .Lbad_put_user
6972
ASM_STAC
@@ -75,9 +78,7 @@ SYM_FUNC_END(__put_user_4)
7578
EXPORT_SYMBOL(__put_user_4)
7679

7780
SYM_FUNC_START(__put_user_8)
78-
ENTER
79-
mov TASK_addr_limit(%_ASM_BX),%_ASM_BX
80-
sub $7,%_ASM_BX
81+
LOAD_TASK_SIZE_MINUS_N(7)
8182
cmp %_ASM_BX,%_ASM_CX
8283
jae .Lbad_put_user
8384
ASM_STAC

0 commit comments

Comments
 (0)