Changeset View
Changeset View
Standalone View
Standalone View
head/sys/vm/vm_mmap.c
Show First 20 Lines • Show All 181 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
int | int | ||||
kern_mmap(struct thread *td, uintptr_t addr0, size_t len, int prot, int flags, | kern_mmap(struct thread *td, uintptr_t addr0, size_t len, int prot, int flags, | ||||
int fd, off_t pos) | int fd, off_t pos) | ||||
{ | { | ||||
struct vmspace *vms; | struct vmspace *vms; | ||||
struct file *fp; | struct file *fp; | ||||
struct proc *p; | |||||
vm_offset_t addr; | vm_offset_t addr; | ||||
vm_size_t pageoff, size; | vm_size_t pageoff, size; | ||||
vm_prot_t cap_maxprot; | vm_prot_t cap_maxprot; | ||||
int align, error, max_prot; | int align, error, max_prot; | ||||
cap_rights_t rights; | cap_rights_t rights; | ||||
if ((prot & ~(_PROT_ALL | PROT_MAX(_PROT_ALL))) != 0) | if ((prot & ~(_PROT_ALL | PROT_MAX(_PROT_ALL))) != 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
max_prot = PROT_MAX_EXTRACT(prot); | max_prot = PROT_MAX_EXTRACT(prot); | ||||
prot = PROT_EXTRACT(prot); | prot = PROT_EXTRACT(prot); | ||||
if (max_prot != 0 && (max_prot & prot) != prot) | if (max_prot != 0 && (max_prot & prot) != prot) | ||||
return (EINVAL); | return (EINVAL); | ||||
p = td->td_proc; | |||||
/* | /* | ||||
* Always honor PROT_MAX if set. If not, default to all | * Always honor PROT_MAX if set. If not, default to all | ||||
* permissions unless we're implying maximum permissions. | * permissions unless we're implying maximum permissions. | ||||
* | * | ||||
* XXX: should be tunable per process and ABI. | * XXX: should be tunable per process and ABI. | ||||
*/ | */ | ||||
if (max_prot == 0) | if (max_prot == 0) | ||||
max_prot = (imply_prot_max && prot != PROT_NONE) ? | max_prot = (imply_prot_max && prot != PROT_NONE) ? | ||||
prot : _PROT_ALL; | prot : _PROT_ALL; | ||||
vms = td->td_proc->p_vmspace; | vms = p->p_vmspace; | ||||
fp = NULL; | fp = NULL; | ||||
AUDIT_ARG_FD(fd); | AUDIT_ARG_FD(fd); | ||||
addr = addr0; | addr = addr0; | ||||
/* | /* | ||||
* Ignore old flags that used to be defined but did not do anything. | * Ignore old flags that used to be defined but did not do anything. | ||||
*/ | */ | ||||
flags &= ~(MAP_RESERVED0020 | MAP_RESERVED0040); | flags &= ~(MAP_RESERVED0020 | MAP_RESERVED0040); | ||||
/* | /* | ||||
* Enforce the constraints. | * Enforce the constraints. | ||||
* Mapping of length 0 is only allowed for old binaries. | * Mapping of length 0 is only allowed for old binaries. | ||||
* Anonymous mapping shall specify -1 as filedescriptor and | * Anonymous mapping shall specify -1 as filedescriptor and | ||||
* zero position for new code. Be nice to ancient a.out | * zero position for new code. Be nice to ancient a.out | ||||
* binaries and correct pos for anonymous mapping, since old | * binaries and correct pos for anonymous mapping, since old | ||||
* ld.so sometimes issues anonymous map requests with non-zero | * ld.so sometimes issues anonymous map requests with non-zero | ||||
* pos. | * pos. | ||||
*/ | */ | ||||
if (!SV_CURPROC_FLAG(SV_AOUT)) { | if (!SV_CURPROC_FLAG(SV_AOUT)) { | ||||
if ((len == 0 && curproc->p_osrel >= P_OSREL_MAP_ANON) || | if ((len == 0 && p->p_osrel >= P_OSREL_MAP_ANON) || | ||||
((flags & MAP_ANON) != 0 && (fd != -1 || pos != 0))) | ((flags & MAP_ANON) != 0 && (fd != -1 || pos != 0))) | ||||
return (EINVAL); | return (EINVAL); | ||||
} else { | } else { | ||||
if ((flags & MAP_ANON) != 0) | if ((flags & MAP_ANON) != 0) | ||||
pos = 0; | pos = 0; | ||||
} | } | ||||
if (flags & MAP_STACK) { | if (flags & MAP_STACK) { | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | if ((flags & MAP_SHARED) != 0) { | ||||
cap_rights_set(&rights, CAP_MMAP_W); | cap_rights_set(&rights, CAP_MMAP_W); | ||||
} | } | ||||
if (prot & PROT_EXEC) | if (prot & PROT_EXEC) | ||||
cap_rights_set(&rights, CAP_MMAP_X); | cap_rights_set(&rights, CAP_MMAP_X); | ||||
error = fget_mmap(td, fd, &rights, &cap_maxprot, &fp); | error = fget_mmap(td, fd, &rights, &cap_maxprot, &fp); | ||||
if (error != 0) | if (error != 0) | ||||
goto done; | goto done; | ||||
if ((flags & (MAP_SHARED | MAP_PRIVATE)) == 0 && | if ((flags & (MAP_SHARED | MAP_PRIVATE)) == 0 && | ||||
td->td_proc->p_osrel >= P_OSREL_MAP_FSTRICT) { | p->p_osrel >= P_OSREL_MAP_FSTRICT) { | ||||
error = EINVAL; | error = EINVAL; | ||||
goto done; | goto done; | ||||
} | } | ||||
/* This relies on VM_PROT_* matching PROT_*. */ | /* This relies on VM_PROT_* matching PROT_*. */ | ||||
error = fo_mmap(fp, &vms->vm_map, &addr, size, prot, | error = fo_mmap(fp, &vms->vm_map, &addr, size, prot, | ||||
max_prot & cap_maxprot, flags, pos, td); | max_prot & cap_maxprot, flags, pos, td); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,246 Lines • Show Last 20 Lines |