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 | #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_32 | 79 | #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 */ |
| @@ -17,7 +17,7 @@ struct task_struct; · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | #ifdef CONFIG_X86_IOPL_IOPERM | 18 | #ifdef CONFIG_X86_IOPL_IOPERM |
| 19 | void io_bitmap_share(struct task_struct *tsk); | 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 | void native_tss_update_io_bitmap(void); | 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 | #else | 30 | #else |
| 31 | static inline void io_bitmap_share(struct task_struct *tsk) { } | 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 | static inline void tss_update_io_bitmap(void) { } | 33 | static inline void tss_update_io_bitmap(void) { } |
| 34 | #endif | 34 | #endif |
| 35 | 35 | ||
| @@ -2,8 +2,15 @@ · 1 unmodified line | |||
| 2 | #ifndef _UAPI_ASM_X86_UNISTD_H | 2 | #ifndef _UAPI_ASM_X86_UNISTD_H |
| 3 | #define _UAPI_ASM_X86_UNISTD_H | 3 | #define _UAPI_ASM_X86_UNISTD_H |
| 4 | 4 | ||
| 5 | /* x32 syscall flag bit */ | 5 | /* |
| 6 | #define __X32_SYSCALL_BIT 0x40000000UL | 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 | #ifndef __KERNEL__ | 15 | #ifndef __KERNEL__ |
| 9 | # ifdef __i386__ | 16 | # ifdef __i386__ |
| @@ -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 | /* | 960 | static 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 | */ | ||
| 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) | ||
| 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); | 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 | int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int offset_start, unsigned int size_total) | 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 | 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 | } |
| @@ -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 | ||
| 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 | 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 | ||
| 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; | 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 | } |
| @@ -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 | void exit_thread(struct task_struct *tsk) | 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 | 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 | ||
| @@ -3,7 +3,7 @@ · 2 unmodified lines | |||
| 3 | #define _UAPI_ASM_X86_UNISTD_H | 3 | #define _UAPI_ASM_X86_UNISTD_H |
| 4 | 4 | ||
| 5 | /* x32 syscall flag bit */ | 5 | /* x32 syscall flag bit */ |
| 6 | #define __X32_SYSCALL_BIT 0x40000000UL | 6 | #define __X32_SYSCALL_BIT 0x40000000 |
| 7 | 7 | ||
| 8 | #ifndef __KERNEL__ | 8 | #ifndef __KERNEL__ |
| 9 | # ifdef __i386__ | 9 | # ifdef __i386__ |