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
7474 #define MAX_DMA_PFN ((16UL * 1024 * 1024) >> PAGE_SHIFT)
7575
7676 /* 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))
7878
7979 #ifdef CONFIG_X86_32
8080 /* 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
1717
1818 #ifdef CONFIG_X86_IOPL_IOPERM
1919 void io_bitmap_share(struct task_struct *tsk);
20−void io_bitmap_exit(void);
20+void io_bitmap_exit(struct task_struct *tsk);
2121
2222 void native_tss_update_io_bitmap(void);
2323
@@ -29,7 +29,7 @@ void native_tss_update_io_bitmap(void); · 5 unmodified lines
2929
3030 #else
3131 static inline void io_bitmap_share(struct task_struct *tsk) { }
32−static inline void io_bitmap_exit(void) { }
32+static inline void io_bitmap_exit(struct task_struct *tsk) { }
3333 static inline void tss_update_io_bitmap(void) { }
3434 #endif
3535
arch/x86/include/uapi/asm/unistd.h+9−2
@@ -2,8 +2,15 @@ · 1 unmodified line
22 #ifndef _UAPI_ASM_X86_UNISTD_H
33 #define _UAPI_ASM_X86_UNISTD_H
44
5−/* x32 syscall flag bit */
6−#define __X32_SYSCALL_BIT 0x40000000UL
5+/*
6+ * 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
714
815 #ifndef __KERNEL__
916 # 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
957957 return true;
958958 }
959959
960−/*
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− */
964−static inline void
965−__copy_xstate_to_kernel(void *kbuf, const void *data,
966− unsigned int offset, unsigned int size, unsigned int size_total)
960+static void fill_gap(unsigned to, void **kbuf, unsigned *pos, unsigned *count)
967961 {
968− if (offset < size_total) {
969− unsigned int copy = min(size, size_total - offset);
962+ if (*pos < to) {
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+}
970973
971− memcpy(kbuf + offset, data, copy);
974+static 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;
972985 }
973986 }
974987
@@ -981,8 +994,9 @@ __copy_xstate_to_kernel(void *kbuf, const void *data, · 6 unmodified lines
981994 */
982995 int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int offset_start, unsigned int size_total)
983996 {
984− unsigned int offset, size;
985997 struct xstate_header header;
998+ const unsigned off_mxcsr = offsetof(struct fxregs_state, mxcsr);
999+ unsigned count = size_total;
9861000 int i;
9871001
9881002 /*
@@ -998,46 +1012,42 @@ int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int of · 9 unmodified lines
9981012 header.xfeatures = xsave->header.xfeatures;
9991013 header.xfeatures &= ~XFEATURE_MASK_SUPERVISOR;
10001014
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);
10011032 /*
10021033 * Copy xregs_state->header:
10031034 */
1004− offset = offsetof(struct xregs_state, header);
1005− size = sizeof(header);
1006−
1007− __copy_xstate_to_kernel(kbuf, &header, offset, size, size_total);
1035+ copy_part(offsetof(struct xregs_state, header), sizeof(header),
1036+ &header, &kbuf, &offset_start, &count);
10081037
1009− for (i = 0; i < XFEATURE_MAX; i++) {
1038+ for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
10101039 /*
10111040 * Copy only in-use xstates:
10121041 */
10131042 if ((header.xfeatures >> i) & 1) {
10141043 void *src = __raw_xsave_addr(xsave, i);
10151044
1016− offset = xstate_offsets[i];
1017− size = xstate_sizes[i];
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);
1045+ copy_part(xstate_offsets[i], xstate_sizes[i],
1046+ src, &kbuf, &offset_start, &count);
10241047 }
10251048
10261049 }
1027−
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);
1050+ fill_gap(size_total, &kbuf, &offset_start, &count);
10411051
10421052 return 0;
10431053 }
arch/x86/kernel/ioport.c+11−11
@@ -33,15 +33,15 @@ void io_bitmap_share(struct task_struct *tsk) · 32 unmodified lines
3333 set_tsk_thread_flag(tsk, TIF_IO_BITMAP);
3434 }
3535
36−static void task_update_io_bitmap(void)
36+static void task_update_io_bitmap(struct task_struct *tsk)
3737 {
38− struct thread_struct *t = &current->thread;
38+ struct thread_struct *t = &tsk->thread;
3939
4040 if (t->iopl_emul == 3 || t->io_bitmap) {
4141 /* 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);
4343 } else {
44− clear_thread_flag(TIF_IO_BITMAP);
44+ clear_tsk_thread_flag(tsk, TIF_IO_BITMAP);
4545 /* Invalidate TSS */
4646 preempt_disable();
4747 tss_update_io_bitmap();
@@ -49,12 +49,12 @@ static void task_update_io_bitmap(void) · 1 unmodified line
4949 }
5050 }
5151
52−void io_bitmap_exit(void)
52+void io_bitmap_exit(struct task_struct *tsk)
5353 {
54− struct io_bitmap *iobm = current->thread.io_bitmap;
54+ struct io_bitmap *iobm = tsk->thread.io_bitmap;
5555
56− current->thread.io_bitmap = NULL;
57− task_update_io_bitmap();
56+ tsk->thread.io_bitmap = NULL;
57+ task_update_io_bitmap(tsk);
5858 if (iobm && refcount_dec_and_test(&iobm->refcnt))
5959 kfree(iobm);
6060 }
@@ -102,7 +102,7 @@ long ksys_ioperm(unsigned long from, unsigned long num, int turn_on) · 41 unmodified lines
102102 if (!iobm)
103103 return -ENOMEM;
104104 refcount_set(&iobm->refcnt, 1);
105− io_bitmap_exit();
105+ io_bitmap_exit(current);
106106 }
107107
108108 /*
@@ -134,7 +134,7 @@ long ksys_ioperm(unsigned long from, unsigned long num, int turn_on) · 25 unmodified lines
134134 }
135135 /* All permissions dropped? */
136136 if (max_long == UINT_MAX) {
137− io_bitmap_exit();
137+ io_bitmap_exit(current);
138138 return 0;
139139 }
140140
@@ -192,7 +192,7 @@ SYSCALL_DEFINE1(iopl, unsigned int, level) · 51 unmodified lines
192192 }
193193
194194 t->iopl_emul = level;
195− task_update_io_bitmap();
195+ task_update_io_bitmap(current);
196196
197197 return 0;
198198 }
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
9696 }
9797
9898 /*
99− * Free current thread data structures etc..
99+ * Free thread data structures etc..
100100 */
101101 void exit_thread(struct task_struct *tsk)
102102 {
@@ -104,7 +104,7 @@ void exit_thread(struct task_struct *tsk) · 1 unmodified line
104104 struct fpu *fpu = &t->fpu;
105105
106106 if (test_thread_flag(TIF_IO_BITMAP))
107− io_bitmap_exit();
107+ io_bitmap_exit(tsk);
108108
109109 free_vm86(t);
110110
tools/arch/x86/include/uapi/asm/unistd.h+1−1
@@ -3,7 +3,7 @@ · 2 unmodified lines
33 #define _UAPI_ASM_X86_UNISTD_H
44
55 /* x32 syscall flag bit */
6−#define __X32_SYSCALL_BIT 0x40000000UL
6+#define __X32_SYSCALL_BIT 0x40000000
77
88 #ifndef __KERNEL__
99 # ifdef __i386__