diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -1699,9 +1699,22 @@ static boolean_t note_overflow(const Elf_Note *note, size_t maxsize) { + size_t avail, need; + if (sizeof(*note) > maxsize) return TRUE; - if (note->n_namesz > maxsize - sizeof(*note)) + avail = maxsize - sizeof(*note); + if (note->n_namesz > avail) + return TRUE; + /* + * The descriptor (and rounded name) must also fit inside the + * remaining segment, otherwise a caller that dereferences the + * descriptor (e.g. bsd_trans_osrel()) would read past the end of + * the validated note buffer. + */ + need = roundup2(note->n_namesz, sizeof(Elf32_Addr)) + + roundup2(note->n_descsz, sizeof(Elf32_Addr)); + if (need > avail) return TRUE; return FALSE; }