Hi,

The regress test src/regress/sys/kern/siginfo-fault checks wether
the si_code is set to SEGV_ACCERR after memory access with wrong
permissions has triggert a SIGSEGV.

Relevant commit message of the test is:
    According to POSIX, SIGSEGV should specify SEGV_ACCERR if the memory
    pages are mapped, but the protections don't match the user's access
    attempts, while SEGV_MAPERR should only be specified for pages that
    are unmapped.  Some platforms currently handle this correctly, but not
    all.

This diff changes the behavior of i366 and amd64.  hppa seems to
do something similar.  Changing error form EACCES to EFAULT in amd64
affects only a printf, so I removed the useless code.  Also change
rv to errno in i386 to make it look like amd64.

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.54
diff -u -p -r1.54 trap.c
--- arch/amd64/amd64/trap.c     30 Apr 2017 13:04:49 -0000      1.54
+++ arch/amd64/amd64/trap.c     13 Jul 2017 12:31:28 -0000
@@ -362,9 +362,6 @@ faultcommon:
                        KERNEL_UNLOCK();
                        goto out;
                }
-               if (error == EACCES) {
-                       error = EFAULT;
-               }
 
                if (type == T_PAGEFLT) {
                        if (pcb->pcb_onfault != 0) {
@@ -389,7 +386,8 @@ faultcommon:
                        frame_dump(frame);
 #endif
                        sv.sival_ptr = (void *)fa;
-                       trapsignal(p, SIGSEGV, T_PAGEFLT, SEGV_MAPERR, sv);
+                       trapsignal(p, SIGSEGV, T_PAGEFLT,
+                           error == EACCES ? SEGV_ACCERR : SEGV_MAPERR, 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.130
diff -u -p -r1.130 trap.c
--- arch/i386/i386/trap.c       30 Apr 2017 13:04:49 -0000      1.130
+++ arch/i386/i386/trap.c       13 Jul 2017 12:33:30 -0000
@@ -373,7 +373,7 @@ trap(struct trapframe *frame)
                vaddr_t va, fa;
                struct vmspace *vm;
                struct vm_map *map;
-               int rv;
+               int error;
 
                cr2 = rcr2();
                KERNEL_LOCK();
@@ -406,12 +406,12 @@ trap(struct trapframe *frame)
                if (curcpu()->ci_inatomic == 0 || map == kernel_map) {
                        onfault = p->p_addr->u_pcb.pcb_onfault;
                        p->p_addr->u_pcb.pcb_onfault = NULL;
-                       rv = uvm_fault(map, va, 0, ftype);
+                       error = uvm_fault(map, va, 0, ftype);
                        p->p_addr->u_pcb.pcb_onfault = onfault;
                } else
-                       rv = EFAULT;
+                       error = EFAULT;
 
-               if (rv == 0) {
+               if (error == 0) {
                        if (map != kernel_map)
                                uvm_grow(p, va);
                        if (type == T_PAGEFLT) {
@@ -428,11 +428,12 @@ trap(struct trapframe *frame)
                                goto copyfault;
                        }
                        printf("uvm_fault(%p, 0x%lx, 0, %d) -> %x\n",
-                           map, va, ftype, rv);
+                           map, va, ftype, error);
                        goto we_re_toast;
                }
                sv.sival_int = fa;
-               trapsignal(p, SIGSEGV, vftype, SEGV_MAPERR, sv);
+               trapsignal(p, SIGSEGV, vftype,
+                   error == EACCES ? SEGV_ACCERR : SEGV_MAPERR, sv);
                KERNEL_UNLOCK();
                break;
        }

Reply via email to