Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/imgact_elf.c
Show First 20 Lines • Show All 833 Lines • ▼ Show 20 Lines | for (i = 0; i < hdr->e_phnum; i++) { | ||||
switch (phdr[i].p_type) { | switch (phdr[i].p_type) { | ||||
case PT_LOAD: | case PT_LOAD: | ||||
if (n == 0) | if (n == 0) | ||||
baddr = phdr[i].p_vaddr; | baddr = phdr[i].p_vaddr; | ||||
n++; | n++; | ||||
break; | break; | ||||
case PT_INTERP: | case PT_INTERP: | ||||
/* Path to interpreter */ | /* Path to interpreter */ | ||||
if (phdr[i].p_filesz > MAXPATHLEN) { | |||||
uprintf("Invalid PT_INTERP\n"); | |||||
error = ENOEXEC; | |||||
goto ret; | |||||
} | |||||
if (interp != NULL) { | if (interp != NULL) { | ||||
uprintf("Multiple PT_INTERP headers\n"); | uprintf("Multiple PT_INTERP headers\n"); | ||||
error = ENOEXEC; | error = ENOEXEC; | ||||
goto ret; | goto ret; | ||||
} | } | ||||
interp_name_len = phdr[i].p_filesz; | interp_name_len = min(phdr[i].p_filesz, MAXPATHLEN); | ||||
markj: Extra semicolon. | |||||
if (phdr[i].p_offset > PAGE_SIZE || | if (phdr[i].p_offset > PAGE_SIZE || | ||||
interp_name_len > PAGE_SIZE - phdr[i].p_offset) { | interp_name_len > PAGE_SIZE - phdr[i].p_offset) { | ||||
VOP_UNLOCK(imgp->vp, 0); | VOP_UNLOCK(imgp->vp, 0); | ||||
interp_buf = malloc(interp_name_len + 1, M_TEMP, | interp_buf = malloc(interp_name_len + 1, M_TEMP, | ||||
Done Inline ActionsNow userland can specify an arbitrarily large size to a malloc call. markj: Now userland can specify an arbitrarily large size to a malloc call. | |||||
M_WAITOK); | M_WAITOK); | ||||
vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY); | vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY); | ||||
Done Inline Actionsmalloc(M_WAITOK) can't fail. markj: malloc(M_WAITOK) can't fail. | |||||
error = vn_rdwr(UIO_READ, imgp->vp, interp_buf, | error = vn_rdwr(UIO_READ, imgp->vp, interp_buf, | ||||
interp_name_len, phdr[i].p_offset, | interp_name_len, phdr[i].p_offset, | ||||
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, | UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, | ||||
NOCRED, NULL, td); | NOCRED, NULL, td); | ||||
if (error != 0) { | if (error != 0) { | ||||
uprintf("i/o error PT_INTERP %d\n", | uprintf("i/o error PT_INTERP %d\n", | ||||
error); | error); | ||||
goto ret; | goto ret; | ||||
} | } | ||||
interp_buf[interp_name_len] = '\0'; | interp_buf[interp_name_len] = '\0'; | ||||
interp = interp_buf; | interp = interp_buf; | ||||
} else { | } else { | ||||
interp = __DECONST(char *, imgp->image_header) + | interp = __DECONST(char *, imgp->image_header) + | ||||
phdr[i].p_offset; | phdr[i].p_offset; | ||||
} | |||||
if (strlen(interp) >= MAXPATHLEN) { | |||||
uprintf("Invalid PT_INTERP (too long)\n"); | |||||
error = ENOEXEC; | |||||
VOP_UNLOCK(imgp->vp, 0); | |||||
goto ret; | |||||
} | } | ||||
break; | break; | ||||
Done Inline ActionsThe interp != NULL check doesn't seem to be needed. markj: The interp != NULL check doesn't seem to be needed. | |||||
case PT_GNU_STACK: | case PT_GNU_STACK: | ||||
Done Inline Actions"too" markj: "too" | |||||
if (__elfN(nxstack)) | if (__elfN(nxstack)) | ||||
imgp->stack_prot = | imgp->stack_prot = | ||||
__elfN(trans_prot)(phdr[i].p_flags); | __elfN(trans_prot)(phdr[i].p_flags); | ||||
imgp->stack_sz = phdr[i].p_memsz; | imgp->stack_sz = phdr[i].p_memsz; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 200 Lines • ▼ Show 20 Lines | __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) | ||||
imgp->auxargs = elf_auxargs; | imgp->auxargs = elf_auxargs; | ||||
imgp->interpreted = 0; | imgp->interpreted = 0; | ||||
imgp->reloc_base = addr; | imgp->reloc_base = addr; | ||||
imgp->proc->p_osrel = osrel; | imgp->proc->p_osrel = osrel; | ||||
imgp->proc->p_elf_machine = hdr->e_machine; | imgp->proc->p_elf_machine = hdr->e_machine; | ||||
imgp->proc->p_elf_flags = hdr->e_flags; | imgp->proc->p_elf_flags = hdr->e_flags; | ||||
ret: | ret: | ||||
free(interp_buf, M_TEMP); | free(interp_buf, M_TEMP); | ||||
Done Inline ActionsHow can this be preventing a double free? markj: How can this be preventing a double free? | |||||
Done Inline ActionsThis part of the change is not needed. markj: This part of the change is not needed. | |||||
Done Inline ActionsAre you saying there is no way the goto ret's or interp = imgp->image_header) ambrisko: Are you saying there is no way the goto ret's or interp = imgp->image_header)
+ phdr[i]. | |||||
Done Inline ActionsNo, but free(NULL) is a no-op. markj: No, but free(NULL) is a no-op. | |||||
return (error); | return (error); | ||||
} | } | ||||
#define suword __CONCAT(suword, __ELF_WORD_SIZE) | #define suword __CONCAT(suword, __ELF_WORD_SIZE) | ||||
int | int | ||||
__elfN(freebsd_fixup)(register_t **stack_base, struct image_params *imgp) | __elfN(freebsd_fixup)(register_t **stack_base, struct image_params *imgp) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 1,378 Lines • Show Last 20 Lines |
Extra semicolon.