Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_mmap.c
Show All 39 Lines | |||||
* Mapped file (mmap) interface to VM | * Mapped file (mmap) interface to VM | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "opt_compat.h" | #include "opt_compat.h" | ||||
#include "opt_hwpmc_hooks.h" | #include "opt_hwpmc_hooks.h" | ||||
#include "opt_pax.h" | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/capsicum.h> | #include <sys/capsicum.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/sysproto.h> | #include <sys/sysproto.h> | ||||
#include <sys/filedesc.h> | #include <sys/filedesc.h> | ||||
#include <sys/pax.h> | |||||
#include <sys/priv.h> | #include <sys/priv.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/procctl.h> | #include <sys/procctl.h> | ||||
#include <sys/racct.h> | #include <sys/racct.h> | ||||
#include <sys/resource.h> | #include <sys/resource.h> | ||||
#include <sys/resourcevar.h> | #include <sys/resourcevar.h> | ||||
#include <sys/rwlock.h> | #include <sys/rwlock.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
▲ Show 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | sys_mmap(td, uap) | ||||
struct mmap_args *uap; | struct mmap_args *uap; | ||||
{ | { | ||||
#ifdef HWPMC_HOOKS | #ifdef HWPMC_HOOKS | ||||
struct pmckern_map_in pkm; | struct pmckern_map_in pkm; | ||||
#endif | #endif | ||||
struct file *fp; | struct file *fp; | ||||
struct vnode *vp; | struct vnode *vp; | ||||
vm_offset_t addr; | vm_offset_t addr; | ||||
#ifdef PAX_ASLR | |||||
vm_offset_t orig_addr; | |||||
#endif | |||||
vm_size_t size, pageoff; | vm_size_t size, pageoff; | ||||
vm_prot_t cap_maxprot, maxprot; | vm_prot_t cap_maxprot, maxprot; | ||||
void *handle; | void *handle; | ||||
objtype_t handle_type; | objtype_t handle_type; | ||||
int align, error, flags, prot; | int align, error, flags, prot; | ||||
off_t pos; | off_t pos; | ||||
struct vmspace *vms = td->td_proc->p_vmspace; | struct vmspace *vms = td->td_proc->p_vmspace; | ||||
cap_rights_t rights; | cap_rights_t rights; | ||||
addr = (vm_offset_t) uap->addr; | addr = (vm_offset_t) uap->addr; | ||||
#ifdef PAX_ASLR | |||||
orig_addr = addr; | |||||
#endif | |||||
size = uap->len; | size = uap->len; | ||||
prot = uap->prot; | prot = uap->prot; | ||||
flags = uap->flags; | flags = uap->flags; | ||||
pos = uap->pos; | pos = uap->pos; | ||||
fp = NULL; | fp = NULL; | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | if (flags & MAP_FIXED) { | ||||
if (addr < vm_map_min(&vms->vm_map) || | if (addr < vm_map_min(&vms->vm_map) || | ||||
addr + size > vm_map_max(&vms->vm_map)) | addr + size > vm_map_max(&vms->vm_map)) | ||||
return (EINVAL); | return (EINVAL); | ||||
if (addr + size < addr) | if (addr + size < addr) | ||||
return (EINVAL); | return (EINVAL); | ||||
#ifdef MAP_32BIT | #ifdef MAP_32BIT | ||||
if (flags & MAP_32BIT && addr + size > MAP_32BIT_MAX_ADDR) | if (flags & MAP_32BIT && addr + size > MAP_32BIT_MAX_ADDR) | ||||
return (EINVAL); | return (EINVAL); | ||||
} else if (flags & MAP_32BIT) { | } else if (flags & MAP_32BIT) { | ||||
bdrewery: Space missing, addr & 0x0fffffff. | |||||
/* | /* | ||||
* For MAP_32BIT, override the hint if it is too high and | * For MAP_32BIT, override the hint if it is too high and | ||||
* do not bother moving the mapping past the heap (since | * do not bother moving the mapping past the heap (since | ||||
* the heap is usually above 2GB). | * the heap is usually above 2GB). | ||||
*/ | */ | ||||
if (addr + size > MAP_32BIT_MAX_ADDR) | if (addr + size > MAP_32BIT_MAX_ADDR) | ||||
addr = 0; | addr = 0; | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 115 Lines • ▼ Show 20 Lines | if ((flags & MAP_SHARED) != 0) { | ||||
cap_maxprot |= VM_PROT_WRITE; | cap_maxprot |= VM_PROT_WRITE; | ||||
} | } | ||||
handle = (void *)vp; | handle = (void *)vp; | ||||
handle_type = OBJT_VNODE; | handle_type = OBJT_VNODE; | ||||
} | } | ||||
map: | map: | ||||
td->td_fpop = fp; | td->td_fpop = fp; | ||||
maxprot &= cap_maxprot; | maxprot &= cap_maxprot; | ||||
#ifdef PAX_ASLR | |||||
pax_aslr_mmap(td->td_proc, &addr, orig_addr, flags); | |||||
Not Done Inline ActionsWas there some other past use for 'orig_addr', or should this really just be rewriting 'addr' in place? rwatson: Was there some other past use for 'orig_addr', or should this really just be rewriting 'addr'… | |||||
Not Done Inline Actionsop: No. The orig_addr is needed.
https://github.com/HardenedBSD/hardenedBSD/commit/190c95d44fb263a… | |||||
#endif | |||||
/* This relies on VM_PROT_* matching PROT_*. */ | /* This relies on VM_PROT_* matching PROT_*. */ | ||||
error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot, | error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot, | ||||
flags, handle_type, handle, pos); | flags, handle_type, handle, pos); | ||||
td->td_fpop = NULL; | td->td_fpop = NULL; | ||||
#ifdef HWPMC_HOOKS | #ifdef HWPMC_HOOKS | ||||
/* inform hwpmc(4) if an executable is being mapped */ | /* inform hwpmc(4) if an executable is being mapped */ | ||||
if (error == 0 && handle_type == OBJT_VNODE && | if (error == 0 && handle_type == OBJT_VNODE && | ||||
▲ Show 20 Lines • Show All 1,274 Lines • Show Last 20 Lines |
Space missing, addr & 0x0fffffff.