summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2017-07-20 18:22:26 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2017-07-20 18:22:26 +0000
commit9eb9e561d4c9412e4b63122562ceb8ba66cbe135 (patch)
tree8ba85baf26ff8ba61dbffcb4cc85c5d63e599acd /sys
parenta9928f0ba236806bb876d27b0498091c964ec03e (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.c20
-rw-r--r--sys/arch/i386/i386/trap.c15
-rw-r--r--sys/uvm/uvm_fault.c4
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;