address incomplete validation of ELF program headers in execve(2) which could lead
authorjasper <jasper@openbsd.org>
Wed, 12 Jul 2023 19:34:14 +0000 (19:34 +0000)
committerjasper <jasper@openbsd.org>
Wed, 12 Jul 2023 19:34:14 +0000 (19:34 +0000)
to a panic in vmcmd_map_readvn() with a malformed binary/interpreter.

original crash found with Melkor, additional validation provided by
guenther@.

ok kettenis@ guenther@ deraadt@

sys/kern/exec_elf.c

index 2d228ff..085eaf4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: exec_elf.c,v 1.182 2023/06/10 19:30:48 kettenis Exp $ */
+/*     $OpenBSD: exec_elf.c,v 1.183 2023/07/12 19:34:14 jasper Exp $   */
 
 /*
  * Copyright (c) 1996 Per Fogelstrom
@@ -325,6 +325,11 @@ elf_load_file(struct proc *p, char *path, struct exec_package *epp,
                goto bad1;
 
        for (i = 0; i < eh.e_phnum; i++) {
+               if ((ph[i].p_align > 1) && !powerof2(ph[i].p_align)) {
+                       error = EINVAL;
+                       goto bad1;
+               }
+
                if (ph[i].p_type == PT_LOAD) {
                        if (ph[i].p_filesz > ph[i].p_memsz ||
                            ph[i].p_memsz == 0) {
@@ -526,6 +531,11 @@ exec_elf_makecmds(struct proc *p, struct exec_package *epp)
        epp->ep_dsize = ELF_NO_ADDR;
 
        for (i = 0, pp = ph; i < eh->e_phnum; i++, pp++) {
+               if ((pp->p_align > 1) && !powerof2(pp->p_align)) {
+                       error = EINVAL;
+                       goto bad;
+               }
+
                if (pp->p_type == PT_INTERP && !interp) {
                        if (pp->p_filesz < 2 || pp->p_filesz > MAXPATHLEN)
                                goto bad;
@@ -560,7 +570,7 @@ exec_elf_makecmds(struct proc *p, struct exec_package *epp)
 
        if (eh->e_type == ET_DYN) {
                /* need phdr and load sections for PIE */
-               if (!has_phdr || base_ph == NULL) {
+               if (!has_phdr || base_ph == NULL || base_ph->p_vaddr != 0) {
                        error = EINVAL;
                        goto bad;
                }