- mmrw, mmmmap: reject accesses to unknown pa if securelevel > 0.

- mmmmap: remove physmem check.  it was wrong and superseded by the above.
- mmmmap: remove suser() check.  there's no point to limit the operation
  to root here, given that the almost same thing can be done by
  normal read and write.
This commit is contained in:
yamt 2006-01-19 13:34:11 +00:00
parent 1f8841dea3
commit a76cc9d9c4

View File

@ -1,4 +1,4 @@
/* $NetBSD: mem.c,v 1.61 2005/12/25 18:46:27 rpaulo Exp $ */
/* $NetBSD: mem.c,v 1.62 2006/01/19 13:34:11 yamt Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993
@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mem.c,v 1.61 2005/12/25 18:46:27 rpaulo Exp $");
__KERNEL_RCSID(0, "$NetBSD: mem.c,v 1.62 2006/01/19 13:34:11 yamt Exp $");
#include "opt_compat_netbsd.h"
@ -109,6 +109,7 @@ const struct cdevsw mem_cdevsw = {
nostop, notty, nopoll, mmmmap, nokqfilter,
};
static int check_pa_acc(paddr_t, vm_prot_t);
/*ARGSUSED*/
int
@ -169,6 +170,10 @@ mmrw(dev_t dev, struct uio *uio, int flags)
v = uio->uio_offset;
prot = uio->uio_rw == UIO_READ ? VM_PROT_READ :
VM_PROT_WRITE;
error = check_pa_acc(uio->uio_offset, prot);
if (error) {
break;
}
pmap_enter(pmap_kernel(), (vaddr_t)vmmap,
trunc_page(v), prot, PMAP_WIRED|prot);
pmap_update(pmap_kernel());
@ -223,7 +228,6 @@ mmrw(dev_t dev, struct uio *uio, int flags)
paddr_t
mmmmap(dev_t dev, off_t off, int prot)
{
struct proc *p = curproc; /* XXX */
/*
* /dev/mem is the only one that makes sense through this
@ -234,9 +238,42 @@ mmmmap(dev_t dev, off_t off, int prot)
* pager in mmap().
*/
if (minor(dev) != DEV_MEM)
return (-1);
return -1;
if ((u_int)off > ctob(physmem) && suser(p->p_ucred, &p->p_acflag) != 0)
return (-1);
return (x86_btop((u_int)off));
if (check_pa_acc(off, prot) != 0) {
return -1;
}
return x86_btop(off);
}
/* ---------------------------------------- */
#include <sys/kcore.h>
/*
* check_pa_acc: check if given pa is accessible.
*/
static int
check_pa_acc(paddr_t pa, vm_prot_t prot)
{
extern phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];
extern int mem_cluster_cnt;
int i;
if (securelevel <= 0) {
return 0;
}
for (i = 0; i < mem_cluster_cnt; i++) {
const phys_ram_seg_t *seg = &mem_clusters[i];
paddr_t start = seg->start;
if (start <= pa && pa - start <= seg->size) {
return 0;
}
}
return EPERM;
}