提交 f72a249b 编写于 作者: A Andy Lutomirski 提交者: Borislav Petkov

x86/fpu: Add address range checks to copy_user_to_xstate()

copy_user_to_xstate() uses __copy_from_user(), which provides a negligible
speedup.  Fortunately, both call sites are at least almost correct.

__fpu__restore_sig() checks access_ok() with xstate_sigframe_size()
length and ptrace regset access uses fpu_user_xstate_size. These should
be valid upper bounds on the length, so, at worst, this would cause
spurious failures and not accesses to kernel memory.

Nonetheless, this is far more fragile than necessary and none of these
callers are in a hotpath.

Use copy_from_user() instead.
Signed-off-by: NAndy Lutomirski <luto@kernel.org>
Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
Signed-off-by: NBorislav Petkov <bp@suse.de>
Acked-by: NDave Hansen <dave.hansen@linux.intel.com>
Acked-by: NRik van Riel <riel@surriel.com>
Link: https://lkml.kernel.org/r/20210608144346.140254130@linutronix.de
上级 8919f072
...@@ -1190,7 +1190,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf) ...@@ -1190,7 +1190,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf)
offset = offsetof(struct xregs_state, header); offset = offsetof(struct xregs_state, header);
size = sizeof(hdr); size = sizeof(hdr);
if (__copy_from_user(&hdr, ubuf + offset, size)) if (copy_from_user(&hdr, ubuf + offset, size))
return -EFAULT; return -EFAULT;
if (validate_user_xstate_header(&hdr)) if (validate_user_xstate_header(&hdr))
...@@ -1205,7 +1205,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf) ...@@ -1205,7 +1205,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf)
offset = xstate_offsets[i]; offset = xstate_offsets[i];
size = xstate_sizes[i]; size = xstate_sizes[i];
if (__copy_from_user(dst, ubuf + offset, size)) if (copy_from_user(dst, ubuf + offset, size))
return -EFAULT; return -EFAULT;
} }
} }
...@@ -1213,7 +1213,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf) ...@@ -1213,7 +1213,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf)
if (xfeatures_mxcsr_quirk(hdr.xfeatures)) { if (xfeatures_mxcsr_quirk(hdr.xfeatures)) {
offset = offsetof(struct fxregs_state, mxcsr); offset = offsetof(struct fxregs_state, mxcsr);
size = MXCSR_AND_FLAGS_SIZE; size = MXCSR_AND_FLAGS_SIZE;
if (__copy_from_user(&xsave->i387.mxcsr, ubuf + offset, size)) if (copy_from_user(&xsave->i387.mxcsr, ubuf + offset, size))
return -EFAULT; return -EFAULT;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册