Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linux/linux_misc.c
Show First 20 Lines • Show All 257 Lines • ▼ Show 20 Lines | linux_uselib(struct thread *td, struct linux_uselib_args *args) | ||||
struct vnode *vp; | struct vnode *vp; | ||||
struct exec *a_out; | struct exec *a_out; | ||||
struct vattr attr; | struct vattr attr; | ||||
vm_offset_t vmaddr; | vm_offset_t vmaddr; | ||||
unsigned long file_offset; | unsigned long file_offset; | ||||
unsigned long bss_size; | unsigned long bss_size; | ||||
char *library; | char *library; | ||||
ssize_t aresid; | ssize_t aresid; | ||||
int error, locked, writecount; | int error, locked; | ||||
LCONVPATHEXIST(td, args->library, &library); | LCONVPATHEXIST(td, args->library, &library); | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(uselib)) | if (ldebug(uselib)) | ||||
printf(ARGS(uselib, "%s"), library); | printf(ARGS(uselib, "%s"), library); | ||||
#endif | #endif | ||||
Show All 12 Lines | #endif | ||||
NDFREE(&ni, NDF_ONLY_PNBUF); | NDFREE(&ni, NDF_ONLY_PNBUF); | ||||
/* | /* | ||||
* From here on down, we have a locked vnode that must be unlocked. | * From here on down, we have a locked vnode that must be unlocked. | ||||
* XXX: The code below largely duplicates exec_check_permissions(). | * XXX: The code below largely duplicates exec_check_permissions(). | ||||
*/ | */ | ||||
locked = 1; | locked = 1; | ||||
/* Writable? */ | |||||
error = VOP_GET_WRITECOUNT(vp, &writecount); | |||||
if (error != 0) | |||||
goto cleanup; | |||||
if (writecount != 0) { | |||||
error = ETXTBSY; | |||||
goto cleanup; | |||||
} | |||||
/* Executable? */ | /* Executable? */ | ||||
error = VOP_GETATTR(vp, &attr, td->td_ucred); | error = VOP_GETATTR(vp, &attr, td->td_ucred); | ||||
if (error) | if (error) | ||||
goto cleanup; | goto cleanup; | ||||
if ((vp->v_mount->mnt_flag & MNT_NOEXEC) || | if ((vp->v_mount->mnt_flag & MNT_NOEXEC) || | ||||
((attr.va_mode & 0111) == 0) || (attr.va_type != VREG)) { | ((attr.va_mode & 0111) == 0) || (attr.va_type != VREG)) { | ||||
/* EACCESS is what exec(2) returns. */ | /* EACCESS is what exec(2) returns. */ | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
PROC_UNLOCK(td->td_proc); | PROC_UNLOCK(td->td_proc); | ||||
/* | /* | ||||
* Prevent more writers. | * Prevent more writers. | ||||
* XXX: Note that if any of the VM operations fail below we don't | * XXX: Note that if any of the VM operations fail below we don't | ||||
* clear this flag. | * clear this flag. | ||||
*/ | */ | ||||
VOP_SET_TEXT(vp); | error = VOP_SET_TEXT(vp, NULL); | ||||
if (error != 0) | |||||
goto cleanup; | |||||
/* | /* | ||||
* Lock no longer needed | * Lock no longer needed | ||||
*/ | */ | ||||
locked = 0; | locked = 0; | ||||
VOP_UNLOCK(vp, 0); | VOP_UNLOCK(vp, 0); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | #endif | ||||
if (error) | if (error) | ||||
goto cleanup; | goto cleanup; | ||||
} | } | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
printf("mem=%08lx = %08lx %08lx\n", (long)vmaddr, ((long *)vmaddr)[0], | printf("mem=%08lx = %08lx %08lx\n", (long)vmaddr, ((long *)vmaddr)[0], | ||||
((long *)vmaddr)[1]); | ((long *)vmaddr)[1]); | ||||
#endif | #endif | ||||
if (bss_size != 0) { | if (bss_size != 0) { | ||||
/* Calculate BSS start address */ | /* Calculate BSS start address */ | ||||
alc: Doesn't this require a write lock on the map? | |||||
Done Inline ActionsFixed on my branch, I will post the update after some other fixes are done. kib: Fixed on my branch, I will post the update after some other fixes are done. | |||||
vmaddr = trunc_page(a_out->a_entry) + a_out->a_text + | vmaddr = trunc_page(a_out->a_entry) + a_out->a_text + | ||||
a_out->a_data; | a_out->a_data; | ||||
Done Inline ActionsWhy not just set textset = false? We have already acquired a text ref by this point. markj: Why not just set textset = false? We have already acquired a text ref by this point. | |||||
/* allocate some 'anon' space */ | /* allocate some 'anon' space */ | ||||
error = vm_map_find(&td->td_proc->p_vmspace->vm_map, NULL, 0, | error = vm_map_find(&td->td_proc->p_vmspace->vm_map, NULL, 0, | ||||
&vmaddr, bss_size, 0, VMFS_NO_SPACE, VM_PROT_ALL, | &vmaddr, bss_size, 0, VMFS_NO_SPACE, VM_PROT_ALL, | ||||
VM_PROT_ALL, 0); | VM_PROT_ALL, 0); | ||||
if (error) | if (error) | ||||
goto cleanup; | goto cleanup; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,113 Lines • Show Last 20 Lines |
Doesn't this require a write lock on the map?