validate alignment of ELF program headers
authorjasper <jasper@openbsd.org>
Wed, 12 Jul 2023 19:49:06 +0000 (19:49 +0000)
committerjasper <jasper@openbsd.org>
Wed, 12 Jul 2023 19:49:06 +0000 (19:49 +0000)
libexec/ld.so/library.c
libexec/ld.so/library_mquery.c

index 6875207..8e2f44c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: library.c,v 1.90 2023/01/29 20:30:56 gnezdo Exp $ */
+/*     $OpenBSD: library.c,v 1.91 2023/07/12 19:49:06 jasper Exp $ */
 
 /*
  * Copyright (c) 2002 Dale Rahn
@@ -113,6 +113,7 @@ _dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
        Elf_Phdr *ptls = NULL;
        struct stat sb;
 
+#define powerof2(x) ((((x) - 1) & (x)) == 0)
 #define ROUND_PG(x) (((x) + align) & ~(align))
 #define TRUNC_PG(x) ((x) & ~(align))
 
@@ -160,6 +161,14 @@ _dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
         */
        phdp = (Elf_Phdr *)(hbuf + ehdr->e_phoff);
        for (i = 0; i < ehdr->e_phnum; i++, phdp++) {
+               if (phdp->p_align > 1 && !powerof2(phdp->p_align)) {
+                       _dl_printf("%s: ld.so invalid ELF input %s.\n",
+                           __progname, libname);
+                       _dl_close(libfile);
+                       _dl_errno = DL_CANT_MMAP;
+                       return(0);
+               }
+
                switch (phdp->p_type) {
                case PT_LOAD:
                        if (phdp->p_vaddr < minva)
index 93019a0..5777538 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: library_mquery.c,v 1.70 2023/01/29 20:30:56 gnezdo Exp $ */
+/*     $OpenBSD: library_mquery.c,v 1.71 2023/07/12 19:49:06 jasper Exp $ */
 
 /*
  * Copyright (c) 2002 Dale Rahn
@@ -118,6 +118,7 @@ _dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
        char hbuf[4096], *exec_start;
        size_t exec_size;
 
+#define powerof2(x) ((((x) - 1) & (x)) == 0)
 #define ROUND_PG(x) (((x) + align) & ~(align))
 #define TRUNC_PG(x) ((x) & ~(align))
 
@@ -171,6 +172,14 @@ _dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
         */
        phdp = (Elf_Phdr *)(hbuf + ehdr->e_phoff);
        for (i = 0; i < ehdr->e_phnum; i++, phdp++) {
+               if (phdp->p_align > 1 && !powerof2(phdp->p_align)) {
+                       _dl_printf("%s: ld.so invalid ELF input %s.\n",
+                           __progname, libname);
+                       _dl_close(libfile);
+                       _dl_errno = DL_CANT_MMAP;
+                       return(0);
+               }
+
                switch (phdp->p_type) {
                case PT_LOAD:
                        off = (phdp->p_vaddr & align);