diff options
| author | Eric Biggers <ebiggers@google.com> | 2017-09-24 06:59:12 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2017-09-26 03:43:48 -0400 |
| commit | 98c0fad9d60e8b2cd47e15b7bee7df343648f5bb (patch) | |
| tree | 6a0d7c8458c24aebbd592cbfbb7d1068012ee7d6 | |
| parent | 3d703477bcfe8bb57079d97198cf1e342fe1fef9 (diff) | |
x86/fpu: Use validate_xstate_header() to validate the xstate_header in copy_user_to_xstate()
Tighten the checks in copy_user_to_xstate().
Signed-off-by: Eric Biggers <ebiggers@google.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Eric Biggers <ebiggers3@gmail.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Kevin Hao <haokexin@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Michael Halcrow <mhalcrow@google.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rik van Riel <riel@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Wanpeng Li <wanpeng.li@hotmail.com>
Cc: Yu-cheng Yu <yu-cheng.yu@intel.com>
Cc: kernel-hardening@lists.openwall.com
Link: http://lkml.kernel.org/r/20170924105913.9157-10-mingo@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
| -rw-r--r-- | arch/x86/kernel/fpu/xstate.c | 16 |
1 files changed, 5 insertions, 11 deletions
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index b6d78b78b5c2..f1d5476c9022 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c | |||
| @@ -1188,16 +1188,15 @@ int copy_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf) | |||
| 1188 | } | 1188 | } |
| 1189 | 1189 | ||
| 1190 | /* | 1190 | /* |
| 1191 | * Convert from a ptrace standard-format user-space buffer to kernel XSAVES format | 1191 | * Convert from a ptrace or sigreturn standard-format user-space buffer to |
| 1192 | * and copy to the target thread. This is called from xstateregs_set() and | 1192 | * kernel XSAVES format and copy to the target thread. This is called from |
| 1193 | * there we check the CPU has XSAVES and a whole standard-sized buffer | 1193 | * xstateregs_set(), as well as potentially from the sigreturn() and |
| 1194 | * exists. | 1194 | * rt_sigreturn() system calls. |
| 1195 | */ | 1195 | */ |
| 1196 | int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf) | 1196 | int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf) |
| 1197 | { | 1197 | { |
| 1198 | unsigned int offset, size; | 1198 | unsigned int offset, size; |
| 1199 | int i; | 1199 | int i; |
| 1200 | u64 allowed_features; | ||
| 1201 | struct xstate_header hdr; | 1200 | struct xstate_header hdr; |
| 1202 | 1201 | ||
| 1203 | offset = offsetof(struct xregs_state, header); | 1202 | offset = offsetof(struct xregs_state, header); |
| @@ -1206,12 +1205,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf) | |||
| 1206 | if (__copy_from_user(&hdr, ubuf + offset, size)) | 1205 | if (__copy_from_user(&hdr, ubuf + offset, size)) |
| 1207 | return -EFAULT; | 1206 | return -EFAULT; |
| 1208 | 1207 | ||
| 1209 | /* | 1208 | if (validate_xstate_header(&hdr)) |
| 1210 | * Reject if the user sets any disabled or supervisor features: | ||
| 1211 | */ | ||
| 1212 | allowed_features = xfeatures_mask & ~XFEATURE_MASK_SUPERVISOR; | ||
| 1213 | |||
| 1214 | if (hdr.xfeatures & ~allowed_features) | ||
| 1215 | return -EINVAL; | 1209 | return -EINVAL; |
| 1216 | 1210 | ||
| 1217 | for (i = 0; i < XFEATURE_MAX; i++) { | 1211 | for (i = 0; i < XFEATURE_MAX; i++) { |
