History

Merge tag 'x86-urgent-2020-05-31' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Thomas Gleixner: "A pile of x86 fixes: - Prevent a memory leak in ioperm which was caused by the stupid assumption that the exit cleanup is always called for current, which is not the case when fork fails after taking a reference on the ioperm bitmap. - Fix an arithmething overflow in the DMA code on 32bit systems - Fill gaps in the xstate copy with defaults instead of leaving them uninitialized - Revert: "Make __X32_SYSCALL_BIT be unsigned long" as it turned out that existing user space fails to build" * tag 'x86-urgent-2020-05-31' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/ioperm: Prevent a memory leak when fork fails x86/dma: Fix max PFN arithmetic overflow on 32 bit systems copy_xstate_to_kernel(): don't leave parts of destination uninitialized x86/syscalls: Revert "x86/syscalls: Make __X32_SYSCALL_BIT be unsigned long"

Linus Torvalds committed 6 years ago

Commit 8fc984a2 parents 3d04282 aa61b7b7 files · +74 −57Browse files

Unified · Split

7 files
  1. arch/x86/include/asm/dma.h +1 −1
  2. arch/x86/include/asm/io_bitmap.h +2 −2
  3. arch/x86/include/uapi/asm/unistd.h +9 −2
  4. arch/x86/kernel/fpu/xstate.c +48 −38
  5. arch/x86/kernel/ioport.c +11 −11
  6. arch/x86/kernel/process.c +2 −2
  7. tools/arch/x86/include/uapi/asm/unistd.h +1 −1
arch/x86/include/asm/dma.h+1−1
@@ -74,7 +74,7 @@ · 73 unmodified lines
74#define MAX_DMA_PFN ((16UL * 1024 * 1024) >> PAGE_SHIFT)74#define MAX_DMA_PFN ((16UL * 1024 * 1024) >> PAGE_SHIFT)
75 75
76/* 4GB broken PCI/AGP hardware bus master zone */76/* 4GB broken PCI/AGP hardware bus master zone */
77#define MAX_DMA32_PFN ((4UL * 1024 * 1024 * 1024) >> PAGE_SHIFT)77#define MAX_DMA32_PFN (1UL << (32 - PAGE_SHIFT))
78 78
79#ifdef CONFIG_X86_3279#ifdef CONFIG_X86_32
80/* The maximum address that we can perform a DMA transfer to on this platform */80/* The maximum address that we can perform a DMA transfer to on this platform */
arch/x86/include/asm/io_bitmap.h+2−2
@@ -17,7 +17,7 @@ struct task_struct; · 16 unmodified lines
17 17
18#ifdef CONFIG_X86_IOPL_IOPERM18#ifdef CONFIG_X86_IOPL_IOPERM
19void io_bitmap_share(struct task_struct *tsk);19void io_bitmap_share(struct task_struct *tsk);
20void io_bitmap_exit(void);20void io_bitmap_exit(struct task_struct *tsk);
21 21
22void native_tss_update_io_bitmap(void);22void native_tss_update_io_bitmap(void);
23 23
@@ -29,7 +29,7 @@ void native_tss_update_io_bitmap(void); · 5 unmodified lines
29 29
30#else30#else
31static inline void io_bitmap_share(struct task_struct *tsk) { }31static inline void io_bitmap_share(struct task_struct *tsk) { }
32static inline void io_bitmap_exit(void) { }32static inline void io_bitmap_exit(struct task_struct *tsk) { }
33static inline void tss_update_io_bitmap(void) { }33static inline void tss_update_io_bitmap(void) { }
34#endif34#endif
35 35
arch/x86/include/uapi/asm/unistd.h+9−2
@@ -2,8 +2,15 @@ · 1 unmodified line
2#ifndef _UAPI_ASM_X86_UNISTD_H2#ifndef _UAPI_ASM_X86_UNISTD_H
3#define _UAPI_ASM_X86_UNISTD_H3#define _UAPI_ASM_X86_UNISTD_H
4 4
5/* x32 syscall flag bit */5/*
6#define __X32_SYSCALL_BIT 0x40000000UL6 * x32 syscall flag bit. Some user programs expect syscall NR macros
7 * and __X32_SYSCALL_BIT to have type int, even though syscall numbers
8 * are, for practical purposes, unsigned long.
9 *
10 * Fortunately, expressions like (nr & ~__X32_SYSCALL_BIT) do the right
11 * thing regardless.
12 */
13#define __X32_SYSCALL_BIT 0x40000000
7 14
8#ifndef __KERNEL__15#ifndef __KERNEL__
9# ifdef __i386__16# ifdef __i386__
arch/x86/kernel/fpu/xstate.c+48−38
@@ -957,18 +957,31 @@ static inline bool xfeatures_mxcsr_quirk(u64 xfeatures) · 956 unmodified lines
957 return true;957 return true;
958}958}
959 959
960/*960static void fill_gap(unsigned to, void **kbuf, unsigned *pos, unsigned *count)
961 * This is similar to user_regset_copyout(), but will not add offset to
962 * the source data pointer or increment pos, count, kbuf, and ubuf.
963 */
964static inline void
965__copy_xstate_to_kernel(void *kbuf, const void *data,
966 unsigned int offset, unsigned int size, unsigned int size_total)
967{961{
968 if (offset < size_total) {962 if (*pos < to) {
969 unsigned int copy = min(size, size_total - offset);963 unsigned size = to - *pos;
964
965 if (size > *count)
966 size = *count;
967 memcpy(*kbuf, (void *)&init_fpstate.xsave + *pos, size);
968 *kbuf += size;
969 *pos += size;
970 *count -= size;
971 }
972}
970 973
971 memcpy(kbuf + offset, data, copy);974static void copy_part(unsigned offset, unsigned size, void *from,
975 void **kbuf, unsigned *pos, unsigned *count)
976{
977 fill_gap(offset, kbuf, pos, count);
978 if (size > *count)
979 size = *count;
980 if (size) {
981 memcpy(*kbuf, from, size);
982 *kbuf += size;
983 *pos += size;
984 *count -= size;
972 }985 }
973}986}
974 987
@@ -981,8 +994,9 @@ __copy_xstate_to_kernel(void *kbuf, const void *data, · 6 unmodified lines
981 */994 */
982int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int offset_start, unsigned int size_total)995int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int offset_start, unsigned int size_total)
983{996{
984 unsigned int offset, size;
985 struct xstate_header header;997 struct xstate_header header;
998 const unsigned off_mxcsr = offsetof(struct fxregs_state, mxcsr);
999 unsigned count = size_total;
986 int i;1000 int i;
987 1001
988 /*1002 /*
@@ -998,46 +1012,42 @@ int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int of · 9 unmodified lines
998 header.xfeatures = xsave->header.xfeatures;1012 header.xfeatures = xsave->header.xfeatures;
999 header.xfeatures &= ~XFEATURE_MASK_SUPERVISOR;1013 header.xfeatures &= ~XFEATURE_MASK_SUPERVISOR;
1000 1014
1015 if (header.xfeatures & XFEATURE_MASK_FP)
1016 copy_part(0, off_mxcsr,
1017 &xsave->i387, &kbuf, &offset_start, &count);
1018 if (header.xfeatures & (XFEATURE_MASK_SSE | XFEATURE_MASK_YMM))
1019 copy_part(off_mxcsr, MXCSR_AND_FLAGS_SIZE,
1020 &xsave->i387.mxcsr, &kbuf, &offset_start, &count);
1021 if (header.xfeatures & XFEATURE_MASK_FP)
1022 copy_part(offsetof(struct fxregs_state, st_space), 128,
1023 &xsave->i387.st_space, &kbuf, &offset_start, &count);
1024 if (header.xfeatures & XFEATURE_MASK_SSE)
1025 copy_part(xstate_offsets[XFEATURE_MASK_SSE], 256,
1026 &xsave->i387.xmm_space, &kbuf, &offset_start, &count);
1027 /*
1028 * Fill xsave->i387.sw_reserved value for ptrace frame:
1029 */
1030 copy_part(offsetof(struct fxregs_state, sw_reserved), 48,
1031 xstate_fx_sw_bytes, &kbuf, &offset_start, &count);
1001 /*1032 /*
1002 * Copy xregs_state->header:1033 * Copy xregs_state->header:
1003 */1034 */
1004 offset = offsetof(struct xregs_state, header);1035 copy_part(offsetof(struct xregs_state, header), sizeof(header),
1005 size = sizeof(header);1036 &header, &kbuf, &offset_start, &count);
1006
1007 __copy_xstate_to_kernel(kbuf, &header, offset, size, size_total);
1008 1037
1009 for (i = 0; i < XFEATURE_MAX; i++) {1038 for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
1010 /*1039 /*
1011 * Copy only in-use xstates:1040 * Copy only in-use xstates:
1012 */1041 */
1013 if ((header.xfeatures >> i) & 1) {1042 if ((header.xfeatures >> i) & 1) {
1014 void *src = __raw_xsave_addr(xsave, i);1043 void *src = __raw_xsave_addr(xsave, i);
1015 1044
1016 offset = xstate_offsets[i];1045 copy_part(xstate_offsets[i], xstate_sizes[i],
1017 size = xstate_sizes[i];1046 src, &kbuf, &offset_start, &count);
1018
1019 /* The next component has to fit fully into the output buffer: */
1020 if (offset + size > size_total)
1021 break;
1022
1023 __copy_xstate_to_kernel(kbuf, src, offset, size, size_total);
1024 }1047 }
1025 1048
1026 }1049 }
1027 1050 fill_gap(size_total, &kbuf, &offset_start, &count);
1028 if (xfeatures_mxcsr_quirk(header.xfeatures)) {
1029 offset = offsetof(struct fxregs_state, mxcsr);
1030 size = MXCSR_AND_FLAGS_SIZE;
1031 __copy_xstate_to_kernel(kbuf, &xsave->i387.mxcsr, offset, size, size_total);
1032 }
1033
1034 /*
1035 * Fill xsave->i387.sw_reserved value for ptrace frame:
1036 */
1037 offset = offsetof(struct fxregs_state, sw_reserved);
1038 size = sizeof(xstate_fx_sw_bytes);
1039
1040 __copy_xstate_to_kernel(kbuf, xstate_fx_sw_bytes, offset, size, size_total);
1041 1051
1042 return 0;1052 return 0;
1043}1053}
arch/x86/kernel/ioport.c+11−11
@@ -33,15 +33,15 @@ void io_bitmap_share(struct task_struct *tsk) · 32 unmodified lines
33 set_tsk_thread_flag(tsk, TIF_IO_BITMAP);33 set_tsk_thread_flag(tsk, TIF_IO_BITMAP);
34}34}
35 35
36static void task_update_io_bitmap(void)36static void task_update_io_bitmap(struct task_struct *tsk)
37{37{
38 struct thread_struct *t = &current->thread;38 struct thread_struct *t = &tsk->thread;
39 39
40 if (t->iopl_emul == 3 || t->io_bitmap) {40 if (t->iopl_emul == 3 || t->io_bitmap) {
41 /* TSS update is handled on exit to user space */41 /* TSS update is handled on exit to user space */
42 set_thread_flag(TIF_IO_BITMAP);42 set_tsk_thread_flag(tsk, TIF_IO_BITMAP);
43 } else {43 } else {
44 clear_thread_flag(TIF_IO_BITMAP);44 clear_tsk_thread_flag(tsk, TIF_IO_BITMAP);
45 /* Invalidate TSS */45 /* Invalidate TSS */
46 preempt_disable();46 preempt_disable();
47 tss_update_io_bitmap();47 tss_update_io_bitmap();
@@ -49,12 +49,12 @@ static void task_update_io_bitmap(void) · 1 unmodified line
49 }49 }
50}50}
51 51
52void io_bitmap_exit(void)52void io_bitmap_exit(struct task_struct *tsk)
53{53{
54 struct io_bitmap *iobm = current->thread.io_bitmap;54 struct io_bitmap *iobm = tsk->thread.io_bitmap;
55 55
56 current->thread.io_bitmap = NULL;56 tsk->thread.io_bitmap = NULL;
57 task_update_io_bitmap();57 task_update_io_bitmap(tsk);
58 if (iobm && refcount_dec_and_test(&iobm->refcnt))58 if (iobm && refcount_dec_and_test(&iobm->refcnt))
59 kfree(iobm);59 kfree(iobm);
60}60}
@@ -102,7 +102,7 @@ long ksys_ioperm(unsigned long from, unsigned long num, int turn_on) · 41 unmodified lines
102 if (!iobm)102 if (!iobm)
103 return -ENOMEM;103 return -ENOMEM;
104 refcount_set(&iobm->refcnt, 1);104 refcount_set(&iobm->refcnt, 1);
105 io_bitmap_exit();105 io_bitmap_exit(current);
106 }106 }
107 107
108 /*108 /*
@@ -134,7 +134,7 @@ long ksys_ioperm(unsigned long from, unsigned long num, int turn_on) · 25 unmodified lines
134 }134 }
135 /* All permissions dropped? */135 /* All permissions dropped? */
136 if (max_long == UINT_MAX) {136 if (max_long == UINT_MAX) {
137 io_bitmap_exit();137 io_bitmap_exit(current);
138 return 0;138 return 0;
139 }139 }
140 140
@@ -192,7 +192,7 @@ SYSCALL_DEFINE1(iopl, unsigned int, level) · 51 unmodified lines
192 }192 }
193 193
194 t->iopl_emul = level;194 t->iopl_emul = level;
195 task_update_io_bitmap();195 task_update_io_bitmap(current);
196 196
197 return 0;197 return 0;
198}198}
arch/x86/kernel/process.c+2−2
@@ -96,7 +96,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) · 95 unmodified lines
96}96}
97 97
98/*98/*
99 * Free current thread data structures etc..99 * Free thread data structures etc..
100 */100 */
101void exit_thread(struct task_struct *tsk)101void exit_thread(struct task_struct *tsk)
102{102{
@@ -104,7 +104,7 @@ void exit_thread(struct task_struct *tsk) · 1 unmodified line
104 struct fpu *fpu = &t->fpu;104 struct fpu *fpu = &t->fpu;
105 105
106 if (test_thread_flag(TIF_IO_BITMAP))106 if (test_thread_flag(TIF_IO_BITMAP))
107 io_bitmap_exit();107 io_bitmap_exit(tsk);
108 108
109 free_vm86(t);109 free_vm86(t);
110 110
tools/arch/x86/include/uapi/asm/unistd.h+1−1
@@ -3,7 +3,7 @@ · 2 unmodified lines
3#define _UAPI_ASM_X86_UNISTD_H3#define _UAPI_ASM_X86_UNISTD_H
4 4
5/* x32 syscall flag bit */5/* x32 syscall flag bit */
6#define __X32_SYSCALL_BIT 0x40000000UL6#define __X32_SYSCALL_BIT 0x40000000
7 7
8#ifndef __KERNEL__8#ifndef __KERNEL__
9# ifdef __i386__9# ifdef __i386__