summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorguido <guido@FreeBSD.org>1998-03-12 19:36:18 +0000
committerguido <guido@FreeBSD.org>1998-03-12 19:36:18 +0000
commit7549a1c33e40ed04f5e11c5f07a183a1051a076d (patch)
treeeb5616184cae15f22a019874c8520003b72981d0
parent96f309afbdb8388d731e4a19fad3a087904e44ba (diff)
downloadFreeBSD-src-7549a1c33e40ed04f5e11c5f07a183a1051a076d.zip
FreeBSD-src-7549a1c33e40ed04f5e11c5f07a183a1051a076d.tar.gz
Fix for mmap of char devices bug as described in OpenBSD advisory of
1998/02/20 Reviewed by: John Dyson Submitted by: "Cy Schubert" <cschuber@uumail.gov.bc.ca>
-rw-r--r--sys/vm/vm_mmap.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index dc41acb..7baf8f3 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -38,7 +38,7 @@
* from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
*
* @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94
- * $Id: vm_mmap.c,v 1.73 1998/02/06 12:14:25 eivind Exp $
+ * $Id: vm_mmap.c,v 1.74 1998/03/07 21:37:01 dyson Exp $
*/
/*
@@ -162,6 +162,7 @@ mmap(p, uap)
vm_prot_t prot, maxprot;
void *handle;
int flags, error;
+ int disablexworkaround;
off_t pos;
addr = (vm_offset_t) uap->addr;
@@ -252,6 +253,26 @@ mmap(p, uap)
pos = 0;
} else {
/*
+ * cdevs does not provide private mappings of any kind.
+ */
+ /*
+ * However, for XIG X server to continue to work,
+ * we should allow the superuser to do it anyway.
+ * We only allow it at securelevel < 1.
+ * (Because the XIG X server writes directly to video
+ * memory via /dev/mem, it should never work at any
+ * other securelevel.
+ * XXX this will have to go
+ */
+ if (securelevel >= 1)
+ disablexworkaround = 1;
+ else
+ disablexworkaround = suser(p->p_ucred,
+ &p->p_acflag);
+ if (vp->v_type == VCHR && disablexworkaround &&
+ (flags & (MAP_PRIVATE|MAP_COPY)))
+ return (EINVAL);
+ /*
* Ensure that file and memory protections are
* compatible. Note that we only worry about
* writability if mapping is shared; in this case,
@@ -265,12 +286,20 @@ mmap(p, uap)
maxprot |= VM_PROT_READ;
else if (prot & PROT_READ)
return (EACCES);
- if (flags & MAP_SHARED) {
- if (fp->f_flag & FWRITE)
- maxprot |= VM_PROT_WRITE;
- else if (prot & PROT_WRITE)
- return (EACCES);
- } else
+ /*
+ * If we are sharing potential changes (either via
+ * MAP_SHARED or via the implicit sharing of character
+ * device mappings), and we are trying to get write
+ * permission although we opened it without asking
+ * for it, bail out. Check for superuser, only if
+ * we're at securelevel < 1, to allow the XIG X server
+ * to continue to work.
+ */
+ if (((flags & MAP_SHARED) != 0 ||
+ (vp->v_type == VCHR && disablexworkaround)) &&
+ (fp->f_flag & FWRITE) == 0 && (prot & PROT_WRITE) != 0)
+ return (EACCES);
+ else
maxprot |= VM_PROT_WRITE;
handle = (void *)vp;
}
OpenPOWER on IntegriCloud