SCCS-vsn: sys/vm/vm_mmap.c 7.25
*
* from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
*
*
* from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
*
- * @(#)vm_mmap.c 7.24 (Berkeley) %G%
+ * @(#)vm_mmap.c 7.25 (Berkeley) %G%
caddr_t handle;
int flags, error;
caddr_t handle;
int flags, error;
+ prot = uap->prot & VM_PROT_ALL;
flags = uap->flags;
#ifdef DEBUG
if (mmapdebug & MDB_FOLLOW)
printf("mmap(%d): addr %x len %x pro %x flg %x fd %d pos %x\n",
flags = uap->flags;
#ifdef DEBUG
if (mmapdebug & MDB_FOLLOW)
printf("mmap(%d): addr %x len %x pro %x flg %x fd %d pos %x\n",
- p->p_pid, uap->addr, uap->len, uap->prot,
+ p->p_pid, uap->addr, uap->len, prot,
flags, uap->fd, (vm_offset_t)uap->pos);
#endif
/*
flags, uap->fd, (vm_offset_t)uap->pos);
#endif
/*
* Size is implicitly rounded to a page boundary.
*/
addr = (vm_offset_t) uap->addr;
* Size is implicitly rounded to a page boundary.
*/
addr = (vm_offset_t) uap->addr;
- if (((flags & MAP_FIXED) && (addr & PAGE_MASK)) || uap->len < 0 ||
- ((flags & MAP_ANON) && uap->fd != -1))
+ if (((flags & MAP_FIXED) && (addr & PAGE_MASK)) ||
+ (ssize_t)uap->len < 0 || ((flags & MAP_ANON) && uap->fd != -1))
return (EINVAL);
size = (vm_size_t) round_page(uap->len);
/*
return (EINVAL);
size = (vm_size_t) round_page(uap->len);
/*
*/
if (addr == 0 && (flags & MAP_FIXED) == 0)
addr = round_page(p->p_vmspace->vm_daddr + MAXDSIZ);
*/
if (addr == 0 && (flags & MAP_FIXED) == 0)
addr = round_page(p->p_vmspace->vm_daddr + MAXDSIZ);
- /*
- * If we are mapping a file we need to check various
- * file/vnode related things.
- */
+ /*
+ * Mapping blank space is trivial.
+ */
handle = NULL;
maxprot = VM_PROT_ALL;
} else {
/*
* Mapping file, get fp for validation.
handle = NULL;
maxprot = VM_PROT_ALL;
} else {
/*
* Mapping file, get fp for validation.
- * Obtain vnode and make sure it is of appropriate type
+ * Obtain vnode and make sure it is of appropriate type.
*/
if (((unsigned)uap->fd) >= fdp->fd_nfiles ||
(fp = fdp->fd_ofiles[uap->fd]) == NULL)
*/
if (((unsigned)uap->fd) >= fdp->fd_nfiles ||
(fp = fdp->fd_ofiles[uap->fd]) == NULL)
if (fp->f_type != DTYPE_VNODE)
if (fp->f_type != DTYPE_VNODE)
vp = (struct vnode *)fp->f_data;
if (vp->v_type != VREG && vp->v_type != VCHR)
vp = (struct vnode *)fp->f_data;
if (vp->v_type != VREG && vp->v_type != VCHR)
- return(EINVAL);
- /*
- * Ensure that file protection and desired protection
- * are compatible. Note that we only worry about writability
- * if mapping is shared.
- */
- if ((uap->prot & PROT_READ) && (fp->f_flag & FREAD) == 0 ||
- ((flags & MAP_SHARED) &&
- (uap->prot & PROT_WRITE) && (fp->f_flag & FWRITE) == 0))
- return(EACCES);
- handle = (caddr_t)vp;
- * Set maximum protection as dictated by the open file.
+ * Ensure that file and memory protections are compatible.
+ * Note that we only worry about writability if mapping is
+ * shared; in this case, current and max prot are dictated
+ * by the open file.
* XXX use the vnode instead? Problem is: what credentials
* do we use for determination? What if proc does a setuid?
*/
* XXX use the vnode instead? Problem is: what credentials
* do we use for determination? What if proc does a setuid?
*/
+ maxprot = VM_PROT_EXECUTE; /* ??? */
- maxprot |= VM_PROT_READ|VM_PROT_EXECUTE;
- if (fp->f_flag & FWRITE)
+ 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
maxprot |= VM_PROT_WRITE;
maxprot |= VM_PROT_WRITE;
- prot = uap->prot & VM_PROT_ALL;
error = vm_mmap(&p->p_vmspace->vm_map, &addr, size, prot, maxprot,
error = vm_mmap(&p->p_vmspace->vm_map, &addr, size, prot, maxprot,
- flags, handle, (vm_offset_t)uap->pos);
+ flags, handle, (vm_offset_t)uap->pos);
- *retval = (int) addr;
- return(error);
+ *retval = (int)addr;
+ return (error);