Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/imgact_aout.c
Show First 20 Lines • Show All 241 Lines • ▼ Show 20 Lines | #endif | ||||
*/ | */ | ||||
PROC_LOCK(imgp->proc); | PROC_LOCK(imgp->proc); | ||||
if (/* text can't exceed maximum text size */ | if (/* text can't exceed maximum text size */ | ||||
a_out->a_text > maxtsiz || | a_out->a_text > maxtsiz || | ||||
/* data + bss can't exceed rlimit */ | /* data + bss can't exceed rlimit */ | ||||
a_out->a_data + bss_size > lim_cur_proc(imgp->proc, RLIMIT_DATA) || | a_out->a_data + bss_size > lim_cur_proc(imgp->proc, RLIMIT_DATA) || | ||||
racct_set(imgp->proc, RACCT_DATA, a_out->a_data + bss_size) != 0) { | racct_set(imgp->proc, RACCT_DATA, a_out->a_data + bss_size) != 0) { | ||||
PROC_UNLOCK(imgp->proc); | PROC_UNLOCK(imgp->proc); | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
PROC_UNLOCK(imgp->proc); | PROC_UNLOCK(imgp->proc); | ||||
/* | /* | ||||
* Avoid a possible deadlock if the current address space is destroyed | * Avoid a possible deadlock if the current address space is destroyed | ||||
* and that address space maps the locked vnode. In the common case, | * and that address space maps the locked vnode. In the common case, | ||||
* the locked vnode's v_usecount is decremented but remains greater | * the locked vnode's v_usecount is decremented but remains greater | ||||
* than zero. Consequently, the vnode lock is not needed by vrele(). | * than zero. Consequently, the vnode lock is not needed by vrele(). | ||||
* However, in cases where the vnode lock is external, such as nullfs, | * However, in cases where the vnode lock is external, such as nullfs, | ||||
* v_usecount may become zero. | * v_usecount may become zero. | ||||
*/ | */ | ||||
VOP_UNLOCK(imgp->vp, 0); | VOP_UNLOCK(imgp->vp, 0); | ||||
/* | /* | ||||
* Destroy old process VM and create a new one (with a new stack) | * Destroy old process VM and create a new one (with a new stack) | ||||
*/ | */ | ||||
error = exec_new_vmspace(imgp, &aout_sysvec); | error = exec_new_vmspace(imgp, &aout_sysvec); | ||||
vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY); | vn_lock(imgp->vp, LK_SHARED | LK_RETRY); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
/* | /* | ||||
* The vm space can be changed by exec_new_vmspace | * The vm space can be changed by exec_new_vmspace | ||||
*/ | */ | ||||
vmspace = imgp->proc->p_vmspace; | vmspace = imgp->proc->p_vmspace; | ||||
object = imgp->object; | object = imgp->object; | ||||
map = &vmspace->vm_map; | map = &vmspace->vm_map; | ||||
vm_map_lock(map); | vm_map_lock(map); | ||||
vm_object_reference(object); | vm_object_reference(object); | ||||
text_end = virtual_offset + a_out->a_text; | text_end = virtual_offset + a_out->a_text; | ||||
error = vm_map_insert(map, object, | error = vm_map_insert(map, object, | ||||
file_offset, | file_offset, | ||||
virtual_offset, text_end, | virtual_offset, text_end, | ||||
VM_PROT_READ | VM_PROT_EXECUTE, VM_PROT_ALL, | VM_PROT_READ | VM_PROT_EXECUTE, VM_PROT_ALL, | ||||
MAP_COPY_ON_WRITE | MAP_PREFAULT); | MAP_COPY_ON_WRITE | MAP_PREFAULT | MAP_VN_EXEC); | ||||
if (error) { | if (error) { | ||||
vm_map_unlock(map); | vm_map_unlock(map); | ||||
vm_object_deallocate(object); | vm_object_deallocate(object); | ||||
return (error); | return (error); | ||||
} | } | ||||
VOP_SET_TEXT_CHECKED(imgp->vp); | |||||
data_end = text_end + a_out->a_data; | data_end = text_end + a_out->a_data; | ||||
if (a_out->a_data) { | if (a_out->a_data) { | ||||
vm_object_reference(object); | vm_object_reference(object); | ||||
error = vm_map_insert(map, object, | error = vm_map_insert(map, object, | ||||
file_offset + a_out->a_text, | file_offset + a_out->a_text, | ||||
text_end, data_end, | text_end, data_end, | ||||
VM_PROT_ALL, VM_PROT_ALL, | VM_PROT_ALL, VM_PROT_ALL, | ||||
MAP_COPY_ON_WRITE | MAP_PREFAULT); | MAP_COPY_ON_WRITE | MAP_PREFAULT | MAP_VN_EXEC); | ||||
if (error) { | if (error) { | ||||
vm_map_unlock(map); | vm_map_unlock(map); | ||||
vm_object_deallocate(object); | vm_object_deallocate(object); | ||||
return (error); | return (error); | ||||
} | } | ||||
VOP_SET_TEXT_CHECKED(imgp->vp); | |||||
} | } | ||||
if (bss_size) { | if (bss_size) { | ||||
error = vm_map_insert(map, NULL, 0, | error = vm_map_insert(map, NULL, 0, | ||||
data_end, data_end + bss_size, | data_end, data_end + bss_size, | ||||
VM_PROT_ALL, VM_PROT_ALL, 0); | VM_PROT_ALL, VM_PROT_ALL, 0); | ||||
if (error) { | if (error) { | ||||
vm_map_unlock(map); | vm_map_unlock(map); | ||||
Show All 29 Lines |