diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2002-02-14 22:46:45 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2002-02-14 22:46:45 +0000 |
commit | 175b1300f90b82d2121ea12e17b7c27a2ecf8668 (patch) | |
tree | c0b1f8d54db1c03441298ff200aeba7ee209dee1 /sys/uvm | |
parent | 1f50d34fc888244ebd5940b480269e6e7f6f0bb7 (diff) |
Correctly FREF/FRELE in mmap(2).
Diffstat (limited to 'sys/uvm')
-rw-r--r-- | sys/uvm/uvm_mmap.c | 38 |
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); } |