From 393244317a61796bc1d564db2b1a1e79eef7eca0 Mon Sep 17 00:00:00 2001 From: "Wang, Tao" Date: Thu, 6 Jun 2024 16:51:36 +0800 Subject: [PATCH 1/6] [6/6] Add more log to detect badframe Signed-off-by: Wang, Tao --- arch/x86/kernel/fpu/signal.c | 71 +++++++++++++++++++++++++++++------- arch/x86/kernel/signal.c | 33 +++++++++++++---- 2 files changed, 83 insertions(+), 21 deletions(-) diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c index 7f76cb099e66a..da5671e1eb0a8 100644 --- a/arch/x86/kernel/fpu/signal.c +++ b/arch/x86/kernel/fpu/signal.c @@ -46,8 +46,10 @@ static inline int check_xstate_in_sigframe(struct fxregs_state __user *fxbuf, * fpstate layout with out copying the extended state information * in the memory layout. */ - if (__get_user(magic2, (__u32 __user *)(fpstate + fx_sw->xstate_size))) - return -EFAULT; + if (__get_user(magic2, (__u32 __user *)(fpstate + fx_sw->xstate_size))){ + pr_info("IBT.check_xstate_in_sigframe __get_user.magic2 %d\n", magic2); + return -EFAULT; + } if (likely(magic2 == FP_XSTATE_MAGIC2)) return 0; @@ -223,22 +225,40 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) static int __restore_fpregs_from_user(void __user *buf, u64 xrestore, bool fx_only) { + int cret; if (use_xsave()) { u64 init_bv = xfeatures_mask_uabi() & ~xrestore; int ret; - if (likely(!fx_only)) + if (likely(!fx_only)){ ret = xrstor_from_user_sigframe(buf, xrestore); - else + if(ret) + pr_info("IBT.__restore_fpregs_from_user ,fx_only is false ,xrstor_from_user_sigframe ,ret is %d\n",ret); + } + else{ ret = fxrstor_from_user_sigframe(buf); - + if(ret) + pr_info("IBT.__restore_fpregs_from_user ,fx_only is true, fxrstor_from_user_sigframe ,ret is %d\n",ret); + } if (!ret && unlikely(init_bv)) os_xrstor(&init_fpstate.xsave, init_bv); + if (ret) + { + pr_info("IBT.__restore_fpregs_from_user ,ret is %d\n",ret); + } return ret; } else if (use_fxsr()) { - return fxrstor_from_user_sigframe(buf); + cret = fxrstor_from_user_sigframe(buf); + if (cret) + pr_info("IBT.__restore_fpregs_from_user, fxrstor_from_user_sigframe is %d\n",cret); + return cret; + } else { - return frstor_from_user_sigframe(buf); + cret = frstor_from_user_sigframe(buf); + if (cret) + pr_info("IBT.__restore_fpregs_from_user, frstor_from_user_sigframe is %d\n",cret); + return cret; + } } @@ -270,6 +290,7 @@ static int restore_fpregs_from_user(void __user *buf, u64 xrestore, * might preempt current and return to user space with * corrupted FPU registers. */ + pr_info("IBT.restore_fpregs_from_user, ret is %d, fx_only is %d\n, true is 1", ret, fx_only); if (test_thread_flag(TIF_NEED_FPU_LOAD)) __cpu_invalidate_fpregs_state(); fpregs_unlock(); @@ -310,14 +331,17 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx, u64 user_xfeatures = 0; bool fx_only = false; int ret; + int cret; if (use_xsave()) { struct _fpx_sw_bytes fx_sw_user; ret = check_xstate_in_sigframe(buf_fx, &fx_sw_user); if (unlikely(ret)) + { + pr_info("IBT.__fpu_restore_sig, check_xstate_in_sigframe ret is %d\n", ret); return ret; - + } fx_only = !fx_sw_user.magic1; state_size = fx_sw_user.xstate_size; user_xfeatures = fx_sw_user.xfeatures; @@ -332,8 +356,11 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx, * faults. If it does, fall back to the slow path below, going * through the kernel buffer with the enabled pagefault handler. */ - return restore_fpregs_from_user(buf_fx, user_xfeatures, fx_only, + cret = restore_fpregs_from_user(buf_fx, user_xfeatures, fx_only, state_size); + if (cret != 0) + pr_info("IBT.__fpu_restore_sig, restore_fpregs_from_user\n"); + return cret; } /* @@ -342,9 +369,10 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx, * in once the larger state has been copied. */ ret = __copy_from_user(&env, buf, sizeof(env)); - if (ret) + if (ret){ + pr_info("IBT.__fpu_restore_sig, __copy_from_user\n"); return ret; - + } /* * By setting TIF_NEED_FPU_LOAD it is ensured that our xstate is * not modified on context switch and that the xstate is considered @@ -372,16 +400,24 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx, if (use_xsave() && !fx_only) { ret = copy_sigframe_from_user_to_xstate(tsk, buf_fx); if (ret) + { + pr_info("IBT.__fpu_restore_sig, copy_sigframe_from_user_to_xstate ret : %d\n", ret); return ret; + } } else { if (__copy_from_user(&fpu->state.fxsave, buf_fx, sizeof(fpu->state.fxsave))) + { + pr_info("IBT.__fpu_restore_sig, EFAULT"); return -EFAULT; - + } if (IS_ENABLED(CONFIG_X86_64)) { /* Reject invalid MXCSR values. */ if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask) + { + pr_info("IBT.__fpu_restore_sig, EINVAL"); return -EINVAL; + } } else { /* Mask invalid bits out for historical reasons (broken hardware). */ fpu->state.fxsave.mxcsr &= mxcsr_feature_mask; @@ -410,13 +446,19 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx, fpu->state.xsave.header.xfeatures &= mask; ret = os_xrstor_safe(&fpu->state.xsave, xfeatures_mask_all); + if (ret) + pr_info("IBT.__fpu_restore_sig, os_xrstor_safe, ret:%d\n",ret); } else { ret = fxrstor_safe(&fpu->state.fxsave); + if (ret) + pr_info("IBT.__fpu_restore_sig, fxrstor_safe, ret:%d\n",ret); } if (likely(!ret)) fpregs_mark_activate(); - + + if (ret) + pr_info("IBT.__fpu_restore_sig, last ret:%d\n",ret); fpregs_unlock(); return ret; } @@ -470,7 +512,10 @@ int fpu__restore_sig(void __user *buf, int ia32_frame) out: if (unlikely(ret)) + { + pr_info("IBT.fpu__restore_sig, ret is %d\n",ret); fpu__clear_user_states(fpu); + } return ret; } diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index bf10340a9b71d..d8e1e48ef859d 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -84,13 +84,14 @@ static int restore_sigcontext(struct pt_regs *regs, unsigned long uc_flags) { struct sigcontext sc; - + bool cret; /* Always make any pending restarted system calls return -EINTR */ current->restart_block.fn = do_no_restart_syscall; - - if (copy_from_user(&sc, usc, CONTEXT_COPY_SIZE)) + + if (copy_from_user(&sc, usc, CONTEXT_COPY_SIZE)){ + pr_info("IBT.restore_sigcontext sc: %px , usc: %px , size: %d\n",&sc, usc, CONTEXT_COPY_SIZE); return -EFAULT; - + } #ifdef CONFIG_X86_32 set_user_gs(regs, sc.gs); regs->fs = sc.fs; @@ -136,8 +137,11 @@ static int restore_sigcontext(struct pt_regs *regs, force_valid_ss(regs); #endif - return fpu__restore_sig((void __user *)sc.fpstate, + cret = fpu__restore_sig((void __user *)sc.fpstate, IS_ENABLED(CONFIG_X86_32)); + if(cret!=0) + pr_info("IBT.restore_sigcontext cret:%d",cret); + return cret; } static __always_inline int @@ -662,21 +666,34 @@ SYSCALL_DEFINE0(rt_sigreturn) unsigned long uc_flags; frame = (struct rt_sigframe __user *)(regs->sp - sizeof(long)); + if (!access_ok(frame, sizeof(*frame))) + { + pr_info("IBT.rt_sigreturn frame: %px\n", frame); goto badframe; + } if (__get_user(*(__u64 *)&set, (__u64 __user *)&frame->uc.uc_sigmask)) + { + pr_info("IBT.rt_sigreturn __get_user(*(__u64 *)&set, (__u64 __user *)&frame->uc.uc_sigmask)"); goto badframe; + } if (__get_user(uc_flags, &frame->uc.uc_flags)) + { + pr_info("IBT.rt_sigreturn __get_user(uc_flags, &frame->uc.uc_flags)"); goto badframe; - + } set_current_blocked(&set); if (restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags)) + { + pr_info("IBT.restore_sigcontext 1 uc_flags %lu\n", (unsigned long)uc_flags); goto badframe; - + } if (restore_altstack(&frame->uc.uc_stack)) + { + pr_info("IBT.restore_sigcontext 2"); goto badframe; - + } return regs->ax; badframe: From 3676920002c19785b89631fdf3158cb8fe26e059 Mon Sep 17 00:00:00 2001 From: "Wang, Tao" Date: Wed, 12 Jun 2024 16:52:11 +0800 Subject: [PATCH 2/6] [6/12]Setup and clear three CPU features flags XSAVEC,XSAVEOPT,PKU Signed-off-by: Wang, Tao --- arch/x86/kernel/cpu/intel.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index ae7d4c85f4f43..aaf712cc3cab2 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -184,6 +184,12 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c) static void early_init_intel(struct cpuinfo_x86 *c) { u64 misc_enable; + + pr_info("IBT.early_init_intel, clear three CPU feature flags"); + setup_clear_cpu_cap(X86_FEATURE_XSAVEC); + setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); + setup_clear_cpu_cap(X86_FEATURE_PKU); + pr_info("IBT.early_init_intel, clear three CPU feature flags Done"); /* Unmask CPUID levels if masked: */ if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) { From 173f0a0a86a9cc7b6b8d761e35b7080fe6c23da7 Mon Sep 17 00:00:00 2001 From: wangtao-intel Date: Thu, 13 Jun 2024 14:53:52 +0800 Subject: [PATCH 3/6] Update intel.c --- arch/x86/kernel/cpu/intel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index aaf712cc3cab2..05ba9dd537730 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -187,6 +187,7 @@ static void early_init_intel(struct cpuinfo_x86 *c) pr_info("IBT.early_init_intel, clear three CPU feature flags"); setup_clear_cpu_cap(X86_FEATURE_XSAVEC); + setup_clear_cpu_cap(X86_FEATURE_XSAVE); setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); setup_clear_cpu_cap(X86_FEATURE_PKU); pr_info("IBT.early_init_intel, clear three CPU feature flags Done"); From f2f9386840917a3a3da88e6bb25d3211b1a6cd6f Mon Sep 17 00:00:00 2001 From: "Wang, Tao" Date: Mon, 17 Jun 2024 15:12:39 +0800 Subject: [PATCH 4/6] Revert "Update intel.c" This reverts commit 173f0a0a86a9cc7b6b8d761e35b7080fe6c23da7. --- arch/x86/kernel/cpu/intel.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 05ba9dd537730..aaf712cc3cab2 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -187,7 +187,6 @@ static void early_init_intel(struct cpuinfo_x86 *c) pr_info("IBT.early_init_intel, clear three CPU feature flags"); setup_clear_cpu_cap(X86_FEATURE_XSAVEC); - setup_clear_cpu_cap(X86_FEATURE_XSAVE); setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); setup_clear_cpu_cap(X86_FEATURE_PKU); pr_info("IBT.early_init_intel, clear three CPU feature flags Done"); From 093d18578fbb17b750d6eca83f6e7d98de73f136 Mon Sep 17 00:00:00 2001 From: "Wang, Tao" Date: Tue, 18 Jun 2024 17:44:38 +0800 Subject: [PATCH 5/6] [6/18] print the struct of xregs_state Signed-off-by: Wang, Tao --- arch/x86/include/asm/fpu/internal.h | 27 +++++++++++++++++++++++++++ arch/x86/kernel/fpu/signal.c | 4 +++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index 6a6f741edda36..96da565c1f405 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -363,11 +363,38 @@ static inline int xrstor_from_user_sigframe(struct xregs_state __user *buf, u64 u32 lmask = mask; u32 hmask = mask >> 32; int err; + struct fxregs_state *fxstate = xstate->i387; + struct xstate_header *xheader = xstate->header; + stac(); XSTATE_OP(XRSTOR, xstate, lmask, hmask, err); clac(); + if(err){ + //struct fpstate *fpstate = current->thread.fpu.fpstate; + //pr_info("IBT.xrstor_from_user_sigframe, size: %u, user_size: %u, xfeatures: %llu, user_xfeatures: %llu, xfd: %llu, is_valloc: %u, is_guest: %u, is_confidential: %u, in_use: %u\n", + // fpstate->size,fpstate->user_size,fpstate->xfeatures,fpstate->user_xfeatures,fpstate->xfd,fpstate->is_valloc,fpstate->is_guest,fpstate->is_confidential,fpstate->in_use); + pr_info("IBT.xrstor_from_user_sigframe.cwd: 0x%04x\n" + "swd: 0x%04x\n" + "twd: 0x%04x\n" + "fop: 0x%04x\n" + "rip: 0x%016llx\n" + "rdp: 0x%016llx\n" + "fip: 0x%08x\n" + "fcs: 0x%08x\n" + "foo: 0x%08x\n" + "fos: 0x%08x\n" + "mxcsr: 0x%08x\n" + "mxcsr_mask: 0x%08x\n", + fxstate->cwd, fxstate->swd, fxstate->twd, fxstate->fop, + fxstate->rip, fxstate->rdp, fxstate->fip, fxstate->fcs, + fxstate->foo, fxstate->fos, fxstate->mxcsr, fxstate->mxcsr_mask); + + pr_info("IBT.xfeatures: 0x%016llx\n, xcomp_bv: 0x%016llx\n",xheader->xfeatures, xheader->xcomp_bv); + pr_info("IBT.xrstor_from_user_sigframe, lmask: 0x%08x, hmask: 0x%0x8\n",lmask, hmask); + } + return err; } diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c index da5671e1eb0a8..205492cbff33d 100644 --- a/arch/x86/kernel/fpu/signal.c +++ b/arch/x86/kernel/fpu/signal.c @@ -37,8 +37,10 @@ static inline int check_xstate_in_sigframe(struct fxregs_state __user *fxbuf, if (fx_sw->magic1 != FP_XSTATE_MAGIC1 || fx_sw->xstate_size < min_xstate_size || fx_sw->xstate_size > fpu_user_xstate_size || - fx_sw->xstate_size > fx_sw->extended_size) + fx_sw->xstate_size > fx_sw->extended_size){ + printk_ratelimited(KERN_ERR "IBT.check_xstate_in_sigframe, goto setfx directly, process is %s, pid is %i\n",current->comm, current->pid); goto setfx; + } /* * Check for the presence of second magic word at the end of memory From e5344a94889d3f3f55c6119ae824a6bdb5ebb65f Mon Sep 17 00:00:00 2001 From: wangtao-intel Date: Wed, 19 Jun 2024 16:36:18 +0800 Subject: [PATCH 6/6] Update internal.h --- arch/x86/include/asm/fpu/internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index 96da565c1f405..87917a3329624 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -363,8 +363,8 @@ static inline int xrstor_from_user_sigframe(struct xregs_state __user *buf, u64 u32 lmask = mask; u32 hmask = mask >> 32; int err; - struct fxregs_state *fxstate = xstate->i387; - struct xstate_header *xheader = xstate->header; + struct fxregs_state *fxstate = &xstate->i387; + struct xstate_header *xheader = &xstate->header; stac();