Guo Ren <ren_...@c-sky.com> writes:

> --- /dev/null
> +++ b/arch/csky/abiv2/fpu.c
> +void fpu_fpe(struct pt_regs * regs)
> +{
> +     int sig;
> +     unsigned int fesr;
> +     siginfo_t info;
> +
> +     fesr = mfcr("cr<2, 2>");
> +
> +     if(fesr & FPE_ILLE){
> +             info.si_code = ILL_ILLOPC;
> +             sig = SIGILL;
> +     }
> +     else if(fesr & FPE_IDC){
> +             info.si_code = ILL_ILLOPN;
> +             sig = SIGILL;
> +     }
> +     else if(fesr & FPE_FEC){
> +             sig = SIGFPE;
> +             if(fesr & FPE_IOC){
> +                     info.si_code = FPE_FLTINV;
> +             }
> +             else if(fesr & FPE_DZC){
> +                     info.si_code = FPE_FLTDIV;
> +             }
> +             else if(fesr & FPE_UFC){
> +                     info.si_code = FPE_FLTUND;
> +             }
> +             else if(fesr & FPE_OFC){
> +                     info.si_code = FPE_FLTOVF;
> +             }
> +             else if(fesr & FPE_IXC){
> +                     info.si_code = FPE_FLTRES;
> +             }
> +             else {
> +                     info.si_code = NSIGFPE;
> +             }
> +     }
> +     else {
> +             info.si_code = NSIGFPE;
> +             sig = SIGFPE;
> +     }
> +     info.si_signo = SIGFPE;
> +     info.si_errno = 0;
> +     info.si_addr = (void *)regs->pc;
> +     force_sig_info(sig, &info, current);
> +}


This use of sending a signal is buggy.  It results in undefined values
being copied to userspace.

Userspace should never be sent NSIGXXX as a si_code.  You can use
FPE_FLTUNK for this default case.

In new code please use force_sig_fault instead of force_sig_info in new
code.  That saves you the trouble of messing with struct siginfo.

Thank you very much,
Eric Biederman

Reply via email to