summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_trap.c
diff options
context:
space:
mode:
authordg <dg@FreeBSD.org>1993-11-28 09:28:54 +0000
committerdg <dg@FreeBSD.org>1993-11-28 09:28:54 +0000
commit1b23af429b7543685abb9ca7dab6605819353d17 (patch)
tree981bfd5da5e60c8b613256f7c074b6d01d640725 /sys/kern/subr_trap.c
parent7f3ca7c5402255f79207d7ac3abe5e9fca0da83e (diff)
downloadFreeBSD-src-1b23af429b7543685abb9ca7dab6605819353d17.zip
FreeBSD-src-1b23af429b7543685abb9ca7dab6605819353d17.tar.gz
Patch from Gene Stark:
Subject: Page fault in PTE area fails in copyout Index: sys/i386/i386/trap.c FreeBSD-1.0.2 Description: Reading files of several megabytes into Emacs, or many small files all at once, would fail with "IO error - bad address". Repeat-By: The bug can be exercised by a test program that malloc()'s a 5MB chunk of memory, and then, without accessing the memory first, filling it with data from a file using read(). (I read 64k chunks from /dev/wd0d into successive 64k regions of the 5MB chunk.) The read() will fail with EFAULT at the first virtual address boundary that is a multiple of 0x400000. Fix: The problem was code in sys/i386/i386/trap.c that tries to figure out what kind of trap occurred and to handle it appropriately. It was interpreting any page fault with virtual address >= vm->vm_maxsaddr as being a user stack segment fault. In fact, addresses >= USRSTACK are in the user structure/PTE area, and if they are handled as stack faults, the proper PTE will not be paged in when it is supposed to be. This situation comes up in copyout() and copyoutstr(), if PTE's are accessed for the first time ever. The page fault on accessing the nonexistent PTE is mishandled as a stack fault, and then the fault that occurs on the subsequent access to the page itself causes copyout to fail with EFAULT.
Diffstat (limited to 'sys/kern/subr_trap.c')
-rw-r--r--sys/kern/subr_trap.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index e967477..d413307 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91
- * $Id: trap.c,v 1.7 1993/11/13 02:25:08 davidg Exp $
+ * $Id: trap.c,v 1.8 1993/11/25 01:31:01 wollman Exp $
*/
/*
@@ -322,7 +322,7 @@ copyfault:
*/
nss = 0;
if ((caddr_t)va >= vm->vm_maxsaddr
- && (caddr_t)va < (caddr_t)VM_MAXUSER_ADDRESS
+ && (caddr_t)va < (caddr_t)USRSTACK
&& map != kernel_map
&& dostacklimits) {
nss = clrnd(btoc((unsigned)vm->vm_maxsaddr
@@ -474,7 +474,9 @@ int trapwrite(addr)
nss = 0;
p = curproc;
vm = p->p_vmspace;
- if ((caddr_t)va >= vm->vm_maxsaddr && dostacklimits) {
+ if ((caddr_t)va >= vm->vm_maxsaddr
+ && (caddr_t)va < (caddr_t)USRSTACK /* EWS 11/27/93 */
+ && dostacklimits) {
nss = clrnd(btoc((unsigned)vm->vm_maxsaddr + MAXSSIZ
- (unsigned)va));
if (nss > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur))
OpenPOWER on IntegriCloud