diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2017-07-20 18:22:26 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2017-07-20 18:22:26 +0000 |
commit | 9eb9e561d4c9412e4b63122562ceb8ba66cbe135 (patch) | |
tree | 8ba85baf26ff8ba61dbffcb4cc85c5d63e599acd /sys | |
parent | a9928f0ba236806bb876d27b0498091c964ec03e (diff) |
Accessing a mmap(2)ed file behind its end should result in a SIGBUS
according to POSIX. Bring regression test and kernel in line for
amd64 and i386. Other architectures have to follow.
OK deraadt@ kettenis@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/amd64/amd64/trap.c | 20 | ||||
-rw-r--r-- | sys/arch/i386/i386/trap.c | 15 | ||||
-rw-r--r-- | sys/uvm/uvm_fault.c | 4 |
3 files changed, 28 insertions, 11 deletions
diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c index 745dc549961..88cc1c147bb 100644 --- a/sys/arch/amd64/amd64/trap.c +++ b/sys/arch/amd64/amd64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.55 2017/07/14 12:20:32 bluhm Exp $ */ +/* $OpenBSD: trap.c,v 1.56 2017/07/20 18:22:25 bluhm Exp $ */ /* $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $ */ /*- @@ -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_OBJERR; + } + sv.sival_ptr = (void *)fa; + trapsignal(p, signal, T_PAGEFLT, sicode, sv); KERNEL_UNLOCK(); break; } diff --git a/sys/arch/i386/i386/trap.c b/sys/arch/i386/i386/trap.c index a8d770aa20a..a72bb5c9f21 100644 --- a/sys/arch/i386/i386/trap.c +++ b/sys/arch/i386/i386/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.131 2017/07/14 12:20:32 bluhm Exp $ */ +/* $OpenBSD: trap.c,v 1.132 2017/07/20 18:22:25 bluhm Exp $ */ /* $NetBSD: trap.c,v 1.95 1996/05/05 06:50:02 mycroft Exp $ */ /*- @@ -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_OBJERR; + } sv.sival_int = fa; - trapsignal(p, SIGSEGV, vftype, - error == EACCES ? SEGV_ACCERR : SEGV_MAPERR, sv); + trapsignal(p, signal, vftype, sicode, sv); KERNEL_UNLOCK(); break; } diff --git a/sys/uvm/uvm_fault.c b/sys/uvm/uvm_fault.c index b0db97bdda1..c521f63f4a3 100644 --- a/sys/uvm/uvm_fault.c +++ b/sys/uvm/uvm_fault.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_fault.c,v 1.91 2016/09/16 01:09:53 dlg Exp $ */ +/* $OpenBSD: uvm_fault.c,v 1.92 2017/07/20 18:22:25 bluhm Exp $ */ /* $NetBSD: uvm_fault.c,v 1.51 2000/08/06 00:22:53 thorpej Exp $ */ /* @@ -1032,7 +1032,7 @@ Case2: } if (!UVM_ET_ISNOFAULT(ufi.entry)) - return (EACCES); /* XXX i/o error */ + return (EIO); uobjpage = PGO_DONTCARE; promote = TRUE; |