summaryrefslogtreecommitdiff
path: root/sys/uvm/uvm_mmap.c
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2002-02-14 22:46:45 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2002-02-14 22:46:45 +0000
commit175b1300f90b82d2121ea12e17b7c27a2ecf8668 (patch)
treec0b1f8d54db1c03441298ff200aeba7ee209dee1 /sys/uvm/uvm_mmap.c
parent1f50d34fc888244ebd5940b480269e6e7f6f0bb7 (diff)
Correctly FREF/FRELE in mmap(2).
Diffstat (limited to 'sys/uvm/uvm_mmap.c')
-rw-r--r--sys/uvm/uvm_mmap.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c
index c5a49768f7a..776a89e6431 100644
--- a/sys/uvm/uvm_mmap.c
+++ b/sys/uvm/uvm_mmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_mmap.c,v 1.33 2001/12/19 08:58:07 art Exp $ */
+/* $OpenBSD: uvm_mmap.c,v 1.34 2002/02/14 22:46:44 art Exp $ */
/* $NetBSD: uvm_mmap.c,v 1.49 2001/02/18 21:19:08 chs Exp $ */
/*
@@ -289,7 +289,7 @@ sys_mmap(p, v, retval)
int flags, fd;
vaddr_t vm_min_address = VM_MIN_ADDRESS;
struct filedesc *fdp = p->p_fd;
- struct file *fp;
+ struct file *fp = NULL;
struct vnode *vp;
caddr_t handle;
int error;
@@ -360,26 +360,33 @@ sys_mmap(p, v, retval)
/*
* check for file mappings (i.e. not anonymous) and verify file.
*/
-
if ((flags & MAP_ANON) == 0) {
if ((fp = fd_getfile(fdp, fd)) == NULL)
return(EBADF);
+ FREF(fp);
+
if (fp->f_type != DTYPE_VNODE)
return (ENODEV); /* only mmap vnodes! */
vp = (struct vnode *)fp->f_data; /* convert to vnode */
if (vp->v_type != VREG && vp->v_type != VCHR &&
- vp->v_type != VBLK)
- return (ENODEV); /* only REG/CHR/BLK support mmap */
+ vp->v_type != VBLK) {
+ error = ENODEV; /* only REG/CHR/BLK support mmap */
+ goto out;
+ }
- if (vp->v_type == VREG && (pos + size) < pos)
- return (EINVAL); /* no offset wrapping */
+ if (vp->v_type == VREG && (pos + size) < pos) {
+ error = EINVAL; /* no offset wrapping */
+ goto out;
+ }
/* special case: catch SunOS style /dev/zero */
if (vp->v_type == VCHR && iszerodev(vp->v_rdev)) {
flags |= MAP_ANON;
+ FRELE(fp);
+ fp = NULL;
goto is_anon;
}
@@ -420,8 +427,10 @@ sys_mmap(p, v, retval)
/* check read access */
if (fp->f_flag & FREAD)
maxprot |= VM_PROT_READ;
- else if (prot & PROT_READ)
- return (EACCES);
+ else if (prot & PROT_READ) {
+ error = EACCES;
+ goto out;
+ }
/* check write access, shared case first */
if (flags & MAP_SHARED) {
@@ -439,9 +448,10 @@ sys_mmap(p, v, retval)
maxprot |= VM_PROT_WRITE;
else if (prot & PROT_WRITE)
return (EPERM);
+ } else if (prot & PROT_WRITE) {
+ error = EACCES;
+ goto out;
}
- else if (prot & PROT_WRITE)
- return (EACCES);
} else {
/* MAP_PRIVATE mappings can always write to */
maxprot |= VM_PROT_WRITE;
@@ -477,7 +487,8 @@ sys_mmap(p, v, retval)
((flags & MAP_PRIVATE) != 0 && (prot & PROT_WRITE) != 0)) {
if (size >
(p->p_rlimit[RLIMIT_DATA].rlim_cur - ctob(p->p_vmspace->vm_dsize))) {
- return (ENOMEM);
+ error = ENOMEM;
+ goto out;
}
}
@@ -492,6 +503,9 @@ sys_mmap(p, v, retval)
/* remember to add offset */
*retval = (register_t)(addr + pageoff);
+out:
+ if (fp)
+ FRELE(fp);
return (error);
}