[BACK]Return to uvm_mmap.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / uvm

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/uvm/uvm_mmap.c between version 1.91.2.3 and 1.91.2.4

version 1.91.2.3, 2007/02/26 09:12:31 version 1.91.2.4, 2007/09/03 14:47:09
Line 89  __KERNEL_RCSID(0, "$NetBSD$");
Line 89  __KERNEL_RCSID(0, "$NetBSD$");
 #define COMPAT_ZERODEV(dev)     (0)  #define COMPAT_ZERODEV(dev)     (0)
 #endif  #endif
   
   #define RANGE_TEST(addr, size, ismmap)                          \
           do {                                                    \
                   vaddr_t vm_min_address = VM_MIN_ADDRESS;        \
                   vaddr_t vm_max_address = VM_MAXUSER_ADDRESS;    \
                   vaddr_t eaddr = addr + size;                    \
                                                                   \
                   if (addr < vm_min_address)                      \
                           return EINVAL;                          \
                   if (eaddr > vm_max_address)                     \
                           return /*CONSTCOND*/                    \
                               ismmap ? EFBIG : EINVAL;            \
                   if (addr > eaddr) /* no wrapping! */            \
                           return /*CONSTCOND*/                    \
                               ismmap ? EOVERFLOW : EINVAL;        \
           } while (/*CONSTCOND*/0)
   
 /*  /*
  * unimplemented VM system calls:   * unimplemented VM system calls:
  */   */
Line 282  sys_mmap(l, v, retval)
Line 298  sys_mmap(l, v, retval)
         register_t *retval;          register_t *retval;
 {  {
         struct sys_mmap_args /* {          struct sys_mmap_args /* {
                 syscallarg(caddr_t) addr;                  syscallarg(void *) addr;
                 syscallarg(size_t) len;                  syscallarg(size_t) len;
                 syscallarg(int) prot;                  syscallarg(int) prot;
                 syscallarg(int) flags;                  syscallarg(int) flags;
Line 297  sys_mmap(l, v, retval)
Line 313  sys_mmap(l, v, retval)
         vsize_t size, pageoff;          vsize_t size, pageoff;
         vm_prot_t prot, maxprot;          vm_prot_t prot, maxprot;
         int flags, fd;          int flags, fd;
         vaddr_t vm_min_address = VM_MIN_ADDRESS, defaddr;          vaddr_t defaddr;
         struct filedesc *fdp = p->p_fd;          struct filedesc *fdp = p->p_fd;
         struct file *fp;          struct file *fp;
         struct vnode *vp;          struct vnode *vp;
Line 332  sys_mmap(l, v, retval)
Line 348  sys_mmap(l, v, retval)
         pos  -= pageoff;          pos  -= pageoff;
         size += pageoff;                        /* add offset */          size += pageoff;                        /* add offset */
         size = (vsize_t)round_page(size);       /* round up */          size = (vsize_t)round_page(size);       /* round up */
         if ((ssize_t) size < 0)  
                 return (EINVAL);                        /* don't allow wrap */  
   
         /*          /*
          * now check (MAP_FIXED) or get (!MAP_FIXED) the "addr"           * now check (MAP_FIXED) or get (!MAP_FIXED) the "addr"
          */           */
   
         if (flags & MAP_FIXED) {          if (flags & MAP_FIXED) {
   
                 /* ensure address and file offset are aligned properly */                  /* ensure address and file offset are aligned properly */
Line 346  sys_mmap(l, v, retval)
Line 359  sys_mmap(l, v, retval)
                 if (addr & PAGE_MASK)                  if (addr & PAGE_MASK)
                         return (EINVAL);                          return (EINVAL);
   
                 if (VM_MAXUSER_ADDRESS > 0 &&                  RANGE_TEST(addr, size, 1);
                     (addr + size) > VM_MAXUSER_ADDRESS)  
                         return (EFBIG);  
                 if (vm_min_address > 0 && addr < vm_min_address)  
                         return (EINVAL);  
                 if (addr > addr + size)  
                         return (EOVERFLOW);             /* no wrapping! */  
   
         } else if (addr == 0 || !(flags & MAP_TRYFIXED)) {          } else if (addr == 0 || !(flags & MAP_TRYFIXED)) {
   
Line 439  sys_mmap(l, v, retval)
Line 446  sys_mmap(l, v, retval)
   
                 maxprot = VM_PROT_EXECUTE;                  maxprot = VM_PROT_EXECUTE;
   
 #if NVERIEXEC > 0  
                 /*  
                  * Check if the file can be executed indirectly.  
                  */  
                 if (veriexec_verify(l, vp, "(mmap)", VERIEXEC_INDIRECT, NULL)) {  
                         /*  
                          * Don't allow executable mappings if we can't  
                          * indirectly execute the file.  
                          */  
                         if (prot & VM_PROT_EXECUTE)  
                                 return (EPERM);  
   
                         /*  
                          * Strip the executable bit from 'maxprot' to make sure  
                          * it can't be made executable later.  
                          */  
                         maxprot &= ~VM_PROT_EXECUTE;  
                 }  
 #endif /* NVERIEXEC > 0 */  
   
                 /* check read access */                  /* check read access */
                 if (fp->f_flag & FREAD)                  if (fp->f_flag & FREAD)
                         maxprot |= VM_PROT_READ;                          maxprot |= VM_PROT_READ;
Line 520  sys_mmap(l, v, retval)
Line 507  sys_mmap(l, v, retval)
                 }                  }
         }          }
   
   #if NVERIEXEC > 0
           if (handle != NULL) {
                   /*
                    * Check if the file can be executed indirectly.
                    *
                    * XXX: This gives false warnings about "Incorrect access type"
                    * XXX: if the mapping is not executable. Harmless, but will be
                    * XXX: fixed as part of other changes.
                    */
                   if (veriexec_verify(l, handle, "(mmap)", VERIEXEC_INDIRECT,
                       NULL)) {
                           /*
                            * Don't allow executable mappings if we can't
                            * indirectly execute the file.
                            */
                           if (prot & VM_PROT_EXECUTE)
                                   return (EPERM);
   
                           /*
                            * Strip the executable bit from 'maxprot' to make sure
                            * it can't be made executable later.
                            */
                           maxprot &= ~VM_PROT_EXECUTE;
                   }
           }
   #endif /* NVERIEXEC > 0 */
   
 #ifdef PAX_MPROTECT  #ifdef PAX_MPROTECT
         pax_mprotect(l, &prot, &maxprot);          pax_mprotect(l, &prot, &maxprot);
 #endif /* PAX_MPROTECT */  #endif /* PAX_MPROTECT */
Line 546  int
Line 560  int
 sys___msync13(struct lwp *l, void *v, register_t *retval)  sys___msync13(struct lwp *l, void *v, register_t *retval)
 {  {
         struct sys___msync13_args /* {          struct sys___msync13_args /* {
                 syscallarg(caddr_t) addr;                  syscallarg(void *) addr;
                 syscallarg(size_t) len;                  syscallarg(size_t) len;
                 syscallarg(int) flags;                  syscallarg(int) flags;
         } */ *uap = v;          } */ *uap = v;
Line 581  sys___msync13(struct lwp *l, void *v, re
Line 595  sys___msync13(struct lwp *l, void *v, re
         size += pageoff;          size += pageoff;
         size = (vsize_t)round_page(size);          size = (vsize_t)round_page(size);
   
         /* disallow wrap-around. */          RANGE_TEST(addr, size, 0);
         if (addr + size < addr)  
                 return (EINVAL);  
   
         /*          /*
          * get map           * get map
Line 638  int
Line 650  int
 sys_munmap(struct lwp *l, void *v, register_t *retval)  sys_munmap(struct lwp *l, void *v, register_t *retval)
 {  {
         struct sys_munmap_args /* {          struct sys_munmap_args /* {
                 syscallarg(caddr_t) addr;                  syscallarg(void *) addr;
                 syscallarg(size_t) len;                  syscallarg(size_t) len;
         } */ *uap = v;          } */ *uap = v;
         struct proc *p = l->l_proc;          struct proc *p = l->l_proc;
         vaddr_t addr;          vaddr_t addr;
         vsize_t size, pageoff;          vsize_t size, pageoff;
         struct vm_map *map;          struct vm_map *map;
         vaddr_t vm_min_address = VM_MIN_ADDRESS;  
         struct vm_map_entry *dead_entries;          struct vm_map_entry *dead_entries;
   
         /*          /*
Line 664  sys_munmap(struct lwp *l, void *v, regis
Line 675  sys_munmap(struct lwp *l, void *v, regis
         size += pageoff;          size += pageoff;
         size = (vsize_t)round_page(size);          size = (vsize_t)round_page(size);
   
         if ((int)size < 0)  
                 return (EINVAL);  
         if (size == 0)          if (size == 0)
                 return (0);                  return (0);
   
         /*          RANGE_TEST(addr, size, 0);
          * Check for illegal addresses.  Watch out for address wrap...  
          * Note that VM_*_ADDRESS are not constants due to casts (argh).  
          */  
         if (VM_MAXUSER_ADDRESS > 0 && addr + size > VM_MAXUSER_ADDRESS)  
                 return (EINVAL);  
         if (vm_min_address > 0 && addr < vm_min_address)  
                 return (EINVAL);  
         if (addr > addr + size)  
                 return (EINVAL);  
         map = &p->p_vmspace->vm_map;          map = &p->p_vmspace->vm_map;
   
         /*          /*
Line 708  int
Line 709  int
 sys_mprotect(struct lwp *l, void *v, register_t *retval)  sys_mprotect(struct lwp *l, void *v, register_t *retval)
 {  {
         struct sys_mprotect_args /* {          struct sys_mprotect_args /* {
                 syscallarg(caddr_t) addr;                  syscallarg(void *) addr;
                 syscallarg(size_t) len;                  syscallarg(size_t) len;
                 syscallarg(int) prot;                  syscallarg(int) prot;
         } */ *uap = v;          } */ *uap = v;
Line 735  sys_mprotect(struct lwp *l, void *v, reg
Line 736  sys_mprotect(struct lwp *l, void *v, reg
         size += pageoff;          size += pageoff;
         size = round_page(size);          size = round_page(size);
   
           RANGE_TEST(addr, size, 0);
   
         error = uvm_map_protect(&p->p_vmspace->vm_map, addr, addr + size, prot,          error = uvm_map_protect(&p->p_vmspace->vm_map, addr, addr + size, prot,
                                 false);                                  false);
         return error;          return error;
Line 748  int
Line 751  int
 sys_minherit(struct lwp *l, void *v, register_t *retval)  sys_minherit(struct lwp *l, void *v, register_t *retval)
 {  {
         struct sys_minherit_args /* {          struct sys_minherit_args /* {
                 syscallarg(caddr_t) addr;                  syscallarg(void *) addr;
                 syscallarg(int) len;                  syscallarg(int) len;
                 syscallarg(int) inherit;                  syscallarg(int) inherit;
         } */ *uap = v;          } */ *uap = v;
Line 771  sys_minherit(struct lwp *l, void *v, reg
Line 774  sys_minherit(struct lwp *l, void *v, reg
         size += pageoff;          size += pageoff;
         size = (vsize_t)round_page(size);          size = (vsize_t)round_page(size);
   
         if ((int)size < 0)          RANGE_TEST(addr, size, 0);
                 return (EINVAL);  
         error = uvm_map_inherit(&p->p_vmspace->vm_map, addr, addr + size,          error = uvm_map_inherit(&p->p_vmspace->vm_map, addr, addr + size,
                                 inherit);                                  inherit);
         return error;          return error;
Line 787  int
Line 790  int
 sys_madvise(struct lwp *l, void *v, register_t *retval)  sys_madvise(struct lwp *l, void *v, register_t *retval)
 {  {
         struct sys_madvise_args /* {          struct sys_madvise_args /* {
                 syscallarg(caddr_t) addr;                  syscallarg(void *) addr;
                 syscallarg(size_t) len;                  syscallarg(size_t) len;
                 syscallarg(int) behav;                  syscallarg(int) behav;
         } */ *uap = v;          } */ *uap = v;
Line 809  sys_madvise(struct lwp *l, void *v, regi
Line 812  sys_madvise(struct lwp *l, void *v, regi
         size += pageoff;          size += pageoff;
         size = (vsize_t)round_page(size);          size = (vsize_t)round_page(size);
   
         if ((ssize_t)size <= 0)          RANGE_TEST(addr, size, 0);
                 return (EINVAL);  
   
         switch (advice) {          switch (advice) {
         case MADV_NORMAL:          case MADV_NORMAL:
Line 912  sys_mlock(struct lwp *l, void *v, regist
Line 914  sys_mlock(struct lwp *l, void *v, regist
         size += pageoff;          size += pageoff;
         size = (vsize_t)round_page(size);          size = (vsize_t)round_page(size);
   
         /* disallow wrap-around. */          RANGE_TEST(addr, size, 0);
         if (addr + size < addr)  
                 return (EINVAL);  
   
         if (atop(size) + uvmexp.wired > uvmexp.wiredmax)          if (atop(size) + uvmexp.wired > uvmexp.wiredmax)
                 return (EAGAIN);                  return (EAGAIN);
Line 962  sys_munlock(struct lwp *l, void *v, regi
Line 962  sys_munlock(struct lwp *l, void *v, regi
         size += pageoff;          size += pageoff;
         size = (vsize_t)round_page(size);          size = (vsize_t)round_page(size);
   
         /* disallow wrap-around. */          RANGE_TEST(addr, size, 0);
         if (addr + size < addr)  
                 return (EINVAL);  
   
         error = uvm_map_pageable(&p->p_vmspace->vm_map, addr, addr+size, true,          error = uvm_map_pageable(&p->p_vmspace->vm_map, addr, addr+size, true,
             0);              0);
Line 1115  uvm_mmap(map, addr, size, prot, maxprot,
Line 1113  uvm_mmap(map, addr, size, prot, maxprot,
                         return (EACCES);                          return (EACCES);
   
                 if (vp->v_type != VCHR) {                  if (vp->v_type != VCHR) {
                         error = VOP_MMAP(vp, 0, curlwp->l_cred, curlwp);                          error = VOP_MMAP(vp, prot, curlwp->l_cred, curlwp);
                         if (error) {                          if (error) {
                                 return error;                                  return error;
                         }                          }
                           vref(vp);
                         uobj = uvn_attach((void *)vp, (flags & MAP_SHARED) ?                          uobj = &vp->v_uobj;
                            maxprot : (maxprot & ~VM_PROT_WRITE));  
   
                         /* XXX for now, attach doesn't gain a ref */  
                         VREF(vp);  
   
                         /*                          /*
                          * If the vnode is being mapped with PROT_EXEC,                           * If the vnode is being mapped with PROT_EXEC,

Legend:
Removed from v.1.91.2.3  
changed lines
  Added in v.1.91.2.4

CVSweb <webmaster@jp.NetBSD.org>