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.

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.

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

ok?

bluhm

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