- Fix two possible overflows when testing if ELF program headers are on
the first page: 1. Cast uint16_t operands in a multiplication to unsigned int because otherwise the implicit promotion to int results in a signed multiplication that can overflow and the behaviour on integer overflow is undefined. 2. Replace (offset + size > PAGE_SIZE) with (size > PAGE_SIZE - offset) because the sum may overflow. - Use the same tests to see if the path to the interpreter is on the first page. There's no overflow here because size is already limited by MAXPATHLEN, but the compiler optimises the new tests better. Also fix an off-by-one error. - Simplify tests to see if an ELF note program header is on the first page. This also fixes an off-by-one error. Reviewed by: kib MFC after: 1 week
This commit is contained in:
parent
3b14c753ff
commit
d19d5bf443
@ -661,9 +661,8 @@ __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Only support headers that fit within first page for now */
|
/* Only support headers that fit within first page for now */
|
||||||
/* (multiplication of two Elf_Half fields will not overflow) */
|
|
||||||
if ((hdr->e_phoff > PAGE_SIZE) ||
|
if ((hdr->e_phoff > PAGE_SIZE) ||
|
||||||
(hdr->e_phentsize * hdr->e_phnum) > PAGE_SIZE - hdr->e_phoff) {
|
(u_int)hdr->e_phentsize * hdr->e_phnum > PAGE_SIZE - hdr->e_phoff) {
|
||||||
error = ENOEXEC;
|
error = ENOEXEC;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -743,7 +742,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if ((hdr->e_phoff > PAGE_SIZE) ||
|
if ((hdr->e_phoff > PAGE_SIZE) ||
|
||||||
(hdr->e_phoff + hdr->e_phentsize * hdr->e_phnum) > PAGE_SIZE) {
|
(u_int)hdr->e_phentsize * hdr->e_phnum > PAGE_SIZE - hdr->e_phoff) {
|
||||||
/* Only support headers in first page for now */
|
/* Only support headers in first page for now */
|
||||||
return (ENOEXEC);
|
return (ENOEXEC);
|
||||||
}
|
}
|
||||||
@ -762,8 +761,8 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
|
|||||||
case PT_INTERP:
|
case PT_INTERP:
|
||||||
/* Path to interpreter */
|
/* Path to interpreter */
|
||||||
if (phdr[i].p_filesz > MAXPATHLEN ||
|
if (phdr[i].p_filesz > MAXPATHLEN ||
|
||||||
phdr[i].p_offset >= PAGE_SIZE ||
|
phdr[i].p_offset > PAGE_SIZE ||
|
||||||
phdr[i].p_offset + phdr[i].p_filesz >= PAGE_SIZE)
|
phdr[i].p_filesz > PAGE_SIZE - phdr[i].p_offset)
|
||||||
return (ENOEXEC);
|
return (ENOEXEC);
|
||||||
interp = imgp->image_header + phdr[i].p_offset;
|
interp = imgp->image_header + phdr[i].p_offset;
|
||||||
interp_name_len = phdr[i].p_filesz;
|
interp_name_len = phdr[i].p_filesz;
|
||||||
@ -1553,9 +1552,8 @@ __elfN(parse_notes)(struct image_params *imgp, Elf_Brandnote *checknote,
|
|||||||
const char *note_name;
|
const char *note_name;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (pnote == NULL || pnote->p_offset >= PAGE_SIZE ||
|
if (pnote == NULL || pnote->p_offset > PAGE_SIZE ||
|
||||||
pnote->p_filesz > PAGE_SIZE ||
|
pnote->p_filesz > PAGE_SIZE - pnote->p_offset)
|
||||||
pnote->p_offset + pnote->p_filesz >= PAGE_SIZE)
|
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
note = note0 = (const Elf_Note *)(imgp->image_header + pnote->p_offset);
|
note = note0 = (const Elf_Note *)(imgp->image_header + pnote->p_offset);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user