From 1005c2d36464878b339eadcecd8ee05e5f9d7ae9 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Wed, 26 Jan 2022 20:00:08 +0800 Subject: [PATCH] x86/fpu: Add address range checks to copy_user_to_xstate() mainline inclusion from mainline-v5.13-rc7 commit f72a249b0ba85564c6bfa94d609a70567485a061 category: feature feature: milan cpu bugzilla: https://gitee.com/openeuler/kernel/issues/I4M9PB CVE: NA -------------------------------- 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: Andy Lutomirski Signed-off-by: Thomas Gleixner Signed-off-by: Borislav Petkov Acked-by: Dave Hansen Acked-by: Rik van Riel Link: https://lkml.kernel.org/r/20210608144346.140254130@linutronix.de Reviewed-by: Yunfeng Ye Reviewed-by: Xie XiuQi Signed-off-by: Zheng Zengkai --- arch/x86/kernel/fpu/xstate.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index 80836b94189e..6655e0df2fb7 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c @@ -1242,7 +1242,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf) offset = offsetof(struct xregs_state, header); size = sizeof(hdr); - if (__copy_from_user(&hdr, ubuf + offset, size)) + if (copy_from_user(&hdr, ubuf + offset, size)) return -EFAULT; if (validate_user_xstate_header(&hdr)) @@ -1257,7 +1257,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf) offset = xstate_offsets[i]; size = xstate_sizes[i]; - if (__copy_from_user(dst, ubuf + offset, size)) + if (copy_from_user(dst, ubuf + offset, size)) return -EFAULT; } } @@ -1265,7 +1265,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf) if (xfeatures_mxcsr_quirk(hdr.xfeatures)) { offset = offsetof(struct fxregs_state, mxcsr); 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; } -- GitLab