From 1650c9d4120888ad1bb2fae2eb5e0d81b0c7c522 Mon Sep 17 00:00:00 2001 From: "Wang, Tao" Date: Thu, 6 Jun 2024 16:51:36 +0800 Subject: [PATCH] [6/6] Add more log to detect badframe Signed-off-by: Wang, Tao --- arch/x86/kernel/fpu/signal.c | 34 ++++++++++++++++++++++++++++------ arch/x86/kernel/signal.c | 33 +++++++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c index 7f76cb099e66a..cf741155f5882 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; @@ -316,8 +318,10 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx, 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,6 +336,7 @@ 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. */ + pr_info("IBT.__fpu_restore_sig, restore_fpregs_from_user\n"); return restore_fpregs_from_user(buf_fx, user_xfeatures, fx_only, state_size); } @@ -342,9 +347,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 +378,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,8 +424,12 @@ 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)) @@ -466,11 +484,15 @@ int fpu__restore_sig(void __user *buf, int ia32_frame) NULL, buf); } else { ret = __fpu_restore_sig(buf, buf_fx, ia32_fxstate); + pr_info("IBT.fpu__restore_sig s: %d\n", ret); } 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: