> 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; > >