> Date: Mon, 17 Jul 2017 23:36:17 +0200
> From: Alexander Bluhm <alexander.bl...@gmx.net>
> 
> Hi,
> 
> The tests regress/sys/kern/siginfo-fault accesses an mmap(2)ed file
> behind its end.  Then it expects an SIGBUS, but gets an SIGSEGV.

As you found it, this was a bit controversial.  Theo and I discussed
this and did some software archeology.  I didn't entirely convince
him, but he gave in and won't object to something like this going in.
We both agree that the SIGBUS/SIGSEGV dichotomy is a mess and I think
that given that mess it makes sense to move the posts a bit and get to
a situation where the BUS_XXX and SEGV_XXX codes make a bit more
sense.

> Related commit message is:
>     Additionally, SIGBUS/BUS_ADRERR should be generated instead of SIGSEGV
>     for access to file mapped pages that exceed the end of the file.
>     (Thanks to kettenis@ for suggesting this test.)
> 
> I think this description refers to
> http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html
>     Reference to whole pages within the mapping, but beyond the current
>     length of the object, shall result in a SIGBUS signal.

It does.  However, instead of SIGBUS/BUS_ADRERR it should
SIGBUS/BUS_OBJERR.

> The attached diff fixes that for amd64 and i386 and the test passes.
> 
> ok?

If you can make the BUS_ADRERR -> BUS_OBJERR change (both here and in
the regress test), this is ok kettenis@

I'll make an effort to make sure the regress test passes on other
architectures as well once this is in.


> Index: arch/amd64/amd64/trap.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/amd64/trap.c,v
> retrieving revision 1.55
> diff -u -p -r1.55 trap.c
> --- arch/amd64/amd64/trap.c   14 Jul 2017 12:20:32 -0000      1.55
> +++ arch/amd64/amd64/trap.c   14 Jul 2017 22:54:28 -0000
> @@ -306,6 +306,7 @@ copyfault:
>               struct vm_map *map;
>               vm_prot_t ftype;
>               extern struct vm_map *kernel_map;
> +             int signal, sicode;
>  
>               cr2 = rcr2();
>               KERNEL_LOCK();
> @@ -372,12 +373,14 @@ faultcommon:
>                           map, fa, ftype, error);
>                       goto we_re_toast;
>               }
> +
> +             signal = SIGSEGV;
> +             sicode = SEGV_MAPERR;
>               if (error == ENOMEM) {
>                       printf("UVM: pid %d (%s), uid %d killed:"
>                           " out of swap\n", p->p_p->ps_pid, p->p_p->ps_comm,
>                           p->p_ucred ? (int)p->p_ucred->cr_uid : -1);
> -                     sv.sival_ptr = (void *)fa;
> -                     trapsignal(p, SIGKILL, T_PAGEFLT, SEGV_MAPERR, sv);
> +                     signal = SIGKILL;
>               } else {
>  #ifdef TRAP_SIGDEBUG
>                       printf("pid %d (%s): %s at rip %llx addr %llx\n",
> @@ -385,10 +388,15 @@ faultcommon:
>                           frame->tf_rip, rcr2());
>                       frame_dump(frame);
>  #endif
> -                     sv.sival_ptr = (void *)fa;
> -                     trapsignal(p, SIGSEGV, T_PAGEFLT,
> -                         error == EACCES ? SEGV_ACCERR : SEGV_MAPERR, sv);
>               }
> +             if (error == EACCES)
> +                     sicode = SEGV_ACCERR;
> +             if (error == EIO) {
> +                     signal = SIGBUS;
> +                     sicode = BUS_ADRERR;
> +             }
> +             sv.sival_ptr = (void *)fa;
> +             trapsignal(p, signal, T_PAGEFLT, sicode, sv);
>               KERNEL_UNLOCK();
>               break;
>       }
> Index: arch/i386/i386/trap.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/arch/i386/i386/trap.c,v
> retrieving revision 1.131
> diff -u -p -r1.131 trap.c
> --- arch/i386/i386/trap.c     14 Jul 2017 12:20:32 -0000      1.131
> +++ arch/i386/i386/trap.c     14 Jul 2017 22:55:16 -0000
> @@ -374,6 +374,7 @@ trap(struct trapframe *frame)
>               struct vmspace *vm;
>               struct vm_map *map;
>               int error;
> +             int signal, sicode;
>  
>               cr2 = rcr2();
>               KERNEL_LOCK();
> @@ -431,9 +432,17 @@ trap(struct trapframe *frame)
>                           map, va, ftype, error);
>                       goto we_re_toast;
>               }
> +
> +             signal = SIGSEGV;
> +             sicode = SEGV_MAPERR;
> +             if (error == EACCES)
> +                     sicode = SEGV_ACCERR;
> +             if (error == EIO) {
> +                     signal = SIGBUS;
> +                     sicode = BUS_ADRERR;
> +             }
>               sv.sival_int = fa;
> -             trapsignal(p, SIGSEGV, vftype,
> -                 error == EACCES ? SEGV_ACCERR : SEGV_MAPERR, sv);
> +             trapsignal(p, signal, vftype, sicode, sv);
>               KERNEL_UNLOCK();
>               break;
>       }
> Index: uvm/uvm_fault.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/uvm/uvm_fault.c,v
> retrieving revision 1.91
> diff -u -p -r1.91 uvm_fault.c
> --- uvm/uvm_fault.c   16 Sep 2016 01:09:53 -0000      1.91
> +++ uvm/uvm_fault.c   14 Jul 2017 22:23:22 -0000
> @@ -1032,7 +1032,7 @@ Case2:
>                       }
>  
>                       if (!UVM_ET_ISNOFAULT(ufi.entry))
> -                             return (EACCES); /* XXX i/o error */
> +                             return (EIO);
>  
>                       uobjpage = PGO_DONTCARE;        
>                       promote = TRUE;
> 
> 

Reply via email to