Set up a kernel_map entry for the text segment with protection of

VM_PROT_READ|VM_PROT_EXECUTE.  The previous default (VM_PROT_ALL)
would cause the following scenario:
	- someone attempts to write kernel text (my test was writing
	  to an offset of /dev/kmem which was known to be in the text
	  segment, while in single-user mode).
	- enter trap() with MMU fault (because of RO pte).
	- trap() calls vm_fault(), which looks up vm_map_entry for
	  fauling address.
	- vm_fault interprets write fault and VM_PROT_WRITE (in VM_PROT_ALL)
	  as COW; new page allocated, data copied to new page, new page
	  mapped in at trunc_page(<faulting va>).
	- wow, look at the fireworks!
Fixes two potential symptoms:
	- kernacc() returns TRUE when checking for permission to write
	  an offset in kernel text, which is bogus, since the text has
	  been mapped RO by pmap_bootstrap().
	- Handling of a stray pointer that attempted to scribble into
	  kernel text would not be executed properly.
This commit is contained in:
thorpej 1996-10-19 08:51:33 +00:00
parent e613224229
commit cf9b36ab1d
1 changed files with 8 additions and 2 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.73 1996/10/18 08:57:14 thorpej Exp $ */ /* $NetBSD: machdep.c,v 1.74 1996/10/19 08:51:33 thorpej Exp $ */
/* /*
* Copyright (c) 1988 University of Utah. * Copyright (c) 1988 University of Utah.
@ -201,6 +201,7 @@ consinit()
void void
cpu_startup() cpu_startup()
{ {
extern char *etext;
register unsigned i; register unsigned i;
register caddr_t v, firstaddr; register caddr_t v, firstaddr;
int base, residual; int base, residual;
@ -416,11 +417,16 @@ again:
nbuf, bufpages * CLBYTES); nbuf, bufpages * CLBYTES);
/* /*
* Tell the VM system that page 0 isn't mapped. * Tell the VM system that page 0 isn't mapped and that
* writing to kernel text isn't allowed. If we don't
* do the latter, we might end up COW'ing the text segment!
*/ */
if (vm_map_protect(kernel_map, 0, NBPG, VM_PROT_NONE, TRUE) if (vm_map_protect(kernel_map, 0, NBPG, VM_PROT_NONE, TRUE)
!= KERN_SUCCESS) != KERN_SUCCESS)
panic("can't mark page 0 off-limits"); panic("can't mark page 0 off-limits");
if (vm_map_protect(kernel_map, NBPG, hp300_round_page(&etext),
VM_PROT_READ|VM_PROT_EXECUTE, TRUE) != KERN_SUCCESS)
panic("can't protect kernel text");
/* /*
* Set up CPU-specific registers, cache, etc. * Set up CPU-specific registers, cache, etc.