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"
Unified · Split
| @@ -74,7 +74,7 @@ · 73 unmodified lines | ||
| 74 | 74 | #define MAX_DMA_PFN ((16UL * 1024 * 1024) >> PAGE_SHIFT) |
| 75 | 75 | |
| 76 | 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 | 79 | #ifdef CONFIG_X86_32 |
| 80 | 80 | /* The maximum address that we can perform a DMA transfer to on this platform */ |
| @@ -17,7 +17,7 @@ struct task_struct; · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | #ifdef CONFIG_X86_IOPL_IOPERM |
| 19 | 19 | void io_bitmap_share(struct task_struct *tsk); |
| 20 | −void io_bitmap_exit(void); | |
| 20 | +void io_bitmap_exit(struct task_struct *tsk); | |
| 21 | 21 | |
| 22 | 22 | void 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 | 30 | #else |
| 31 | 31 | 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) { } | |
| 33 | 33 | static inline void tss_update_io_bitmap(void) { } |
| 34 | 34 | #endif |
| 35 | 35 | |
| @@ -2,8 +2,15 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _UAPI_ASM_X86_UNISTD_H |
| 3 | 3 | #define _UAPI_ASM_X86_UNISTD_H |
| 4 | 4 | |
| 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 | |
| 7 | 14 | |
| 8 | 15 | #ifndef __KERNEL__ |
| 9 | 16 | # ifdef __i386__ |
| @@ -957,18 +957,31 @@ static inline bool xfeatures_mxcsr_quirk(u64 xfeatures) · 956 unmodified lines | ||
| 957 | 957 | return true; |
| 958 | 958 | } |
| 959 | 959 | |
| 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) | |
| 967 | 961 | { |
| 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 | +} | |
| 970 | 973 | |
| 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; | |
| 972 | 985 | } |
| 973 | 986 | } |
| 974 | 987 | |
| @@ -981,8 +994,9 @@ __copy_xstate_to_kernel(void *kbuf, const void *data, · 6 unmodified lines | ||
| 981 | 994 | */ |
| 982 | 995 | int 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 | 997 | struct xstate_header header; |
| 998 | + const unsigned off_mxcsr = offsetof(struct fxregs_state, mxcsr); | |
| 999 | + unsigned count = size_total; | |
| 986 | 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 | 1012 | header.xfeatures = xsave->header.xfeatures; |
| 999 | 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 | 1033 | * Copy xregs_state->header: |
| 1003 | 1034 | */ |
| 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); | |
| 1008 | 1037 | |
| 1009 | − for (i = 0; i < XFEATURE_MAX; i++) { | |
| 1038 | + for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) { | |
| 1010 | 1039 | /* |
| 1011 | 1040 | * Copy only in-use xstates: |
| 1012 | 1041 | */ |
| 1013 | 1042 | if ((header.xfeatures >> i) & 1) { |
| 1014 | 1043 | void *src = __raw_xsave_addr(xsave, i); |
| 1015 | 1044 | |
| 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); | |
| 1024 | 1047 | } |
| 1025 | 1048 | |
| 1026 | 1049 | } |
| 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); | |
| 1041 | 1051 | |
| 1042 | 1052 | return 0; |
| 1043 | 1053 | } |
| @@ -33,15 +33,15 @@ void io_bitmap_share(struct task_struct *tsk) · 32 unmodified lines | ||
| 33 | 33 | set_tsk_thread_flag(tsk, TIF_IO_BITMAP); |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | −static void task_update_io_bitmap(void) | |
| 36 | +static void task_update_io_bitmap(struct task_struct *tsk) | |
| 37 | 37 | { |
| 38 | − struct thread_struct *t = ¤t->thread; | |
| 38 | + struct thread_struct *t = &tsk->thread; | |
| 39 | 39 | |
| 40 | 40 | if (t->iopl_emul == 3 || t->io_bitmap) { |
| 41 | 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 | 43 | } else { |
| 44 | − clear_thread_flag(TIF_IO_BITMAP); | |
| 44 | + clear_tsk_thread_flag(tsk, TIF_IO_BITMAP); | |
| 45 | 45 | /* Invalidate TSS */ |
| 46 | 46 | preempt_disable(); |
| 47 | 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 | |
| 52 | −void io_bitmap_exit(void) | |
| 52 | +void 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; | |
| 57 | − task_update_io_bitmap(); | |
| 56 | + tsk->thread.io_bitmap = NULL; | |
| 57 | + task_update_io_bitmap(tsk); | |
| 58 | 58 | if (iobm && refcount_dec_and_test(&iobm->refcnt)) |
| 59 | 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 | 102 | if (!iobm) |
| 103 | 103 | return -ENOMEM; |
| 104 | 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 | 135 | /* All permissions dropped? */ |
| 136 | 136 | if (max_long == UINT_MAX) { |
| 137 | − io_bitmap_exit(); | |
| 137 | + io_bitmap_exit(current); | |
| 138 | 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 | 194 | t->iopl_emul = level; |
| 195 | − task_update_io_bitmap(); | |
| 195 | + task_update_io_bitmap(current); | |
| 196 | 196 | |
| 197 | 197 | return 0; |
| 198 | 198 | } |
| @@ -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 | */ |
| 101 | 101 | void exit_thread(struct task_struct *tsk) |
| 102 | 102 | { |
| @@ -104,7 +104,7 @@ void exit_thread(struct task_struct *tsk) · 1 unmodified line | ||
| 104 | 104 | struct fpu *fpu = &t->fpu; |
| 105 | 105 | |
| 106 | 106 | if (test_thread_flag(TIF_IO_BITMAP)) |
| 107 | − io_bitmap_exit(); | |
| 107 | + io_bitmap_exit(tsk); | |
| 108 | 108 | |
| 109 | 109 | free_vm86(t); |
| 110 | 110 | |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | #define _UAPI_ASM_X86_UNISTD_H |
| 4 | 4 | |
| 5 | 5 | /* x32 syscall flag bit */ |
| 6 | −#define __X32_SYSCALL_BIT 0x40000000UL | |
| 6 | +#define __X32_SYSCALL_BIT 0x40000000 | |
| 7 | 7 | |
| 8 | 8 | #ifndef __KERNEL__ |
| 9 | 9 | # ifdef __i386__ |