Index: sys/kern/imgact_elf.c =================================================================== --- sys/kern/imgact_elf.c +++ sys/kern/imgact_elf.c @@ -839,22 +839,22 @@ break; case PT_INTERP: /* Path to interpreter */ - if (phdr[i].p_filesz > MAXPATHLEN) { - uprintf("Invalid PT_INTERP\n"); - error = ENOEXEC; - goto ret; - } if (interp != NULL) { uprintf("Multiple PT_INTERP headers\n"); error = ENOEXEC; goto ret; } - interp_name_len = phdr[i].p_filesz; + interp_name_len = min(phdr[i].p_filesz, MAXPATHLEN);; if (phdr[i].p_offset > PAGE_SIZE || interp_name_len > PAGE_SIZE - phdr[i].p_offset) { VOP_UNLOCK(imgp->vp, 0); interp_buf = malloc(interp_name_len + 1, M_TEMP, M_WAITOK); + if (interp_buf == NULL) { + uprintf("Failed malloc\n"); + error = ENOEXEC; + goto ret; + } vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY); error = vn_rdwr(UIO_READ, imgp->vp, interp_buf, interp_name_len, phdr[i].p_offset, @@ -870,6 +870,12 @@ interp = __DECONST(char *, imgp->image_header) + 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; case PT_GNU_STACK: if (__elfN(nxstack)) @@ -1088,7 +1094,8 @@ imgp->proc->p_elf_flags = hdr->e_flags; ret: - free(interp_buf, M_TEMP); + if (interp_buf != NULL) + free(interp_buf, M_TEMP); return (error); }