There's a race in kmem(4) between checking whether a page is resident

in the kernel and copying it out, causing a panic when faulting on a
nofault entry. Handle this case gracefully by letting the kernel copy
functions return EFAULT instead. As such this change addresses the
same problem as r154721 does for i386.

MFC after:	3 days
This commit is contained in:
Marius Strobl 2008-08-24 20:53:36 +00:00
parent de8bfff6c9
commit 474dee38bf

View File

@ -388,6 +388,7 @@ trap_pfault(struct thread *td, struct trapframe *tf)
struct proc *p;
vm_offset_t va;
vm_prot_t prot;
vm_map_entry_t entry;
u_long ctx;
int flags;
int type;
@ -461,6 +462,19 @@ trap_pfault(struct thread *td, struct trapframe *tf)
KASSERT(tf->tf_tstate & TSTATE_PRIV,
("trap_pfault: fault on nucleus context from user mode"));
if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
tf->tf_tpc <= (u_long)copy_nofault_end) {
vm_map_lock_read(kernel_map);
if (vm_map_lookup_entry(kernel_map, va, &entry) &&
(entry->eflags & MAP_ENTRY_NOFAULT) != 0) {
tf->tf_tpc = (u_long)copy_fault;
tf->tf_tnpc = tf->tf_tpc + 4;
vm_map_unlock_read(kernel_map);
return (0);
}
vm_map_unlock_read(kernel_map);
}
/*
* We don't have to worry about process locking or stacks in
* the kernel.