Module Name: src Committed By: christos Date: Thu Sep 15 17:45:44 UTC 2016
Modified Files: src/sys/kern: exec_elf.c Log Message: Add debugging. To generate a diff of this commit: cvs rdiff -u -r1.85 -r1.86 src/sys/kern/exec_elf.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/exec_elf.c diff -u src/sys/kern/exec_elf.c:1.85 src/sys/kern/exec_elf.c:1.86 --- src/sys/kern/exec_elf.c:1.85 Wed May 25 13:25:32 2016 +++ src/sys/kern/exec_elf.c Thu Sep 15 13:45:44 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: exec_elf.c,v 1.85 2016/05/25 17:25:32 christos Exp $ */ +/* $NetBSD: exec_elf.c,v 1.86 2016/09/15 17:45:44 christos Exp $ */ /*- * Copyright (c) 1994, 2000, 2005, 2015 The NetBSD Foundation, Inc. @@ -57,7 +57,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.85 2016/05/25 17:25:32 christos Exp $"); +__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.86 2016/09/15 17:45:44 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_pax.h" @@ -110,6 +110,11 @@ int netbsd_elf_probe(struct lwp *, struc static void elf_free_emul_arg(void *); +#ifdef DEBUG_ELF +#define DPRINTF(a, ...) printf("%s: " a "\n", __func__, ##__VA_ARGS__) +#else +#define DPRINTF(a, ...) + /* round up and down to page boundaries. */ #define ELF_ROUND(a, b) (((a) + (b) - 1) & ~((b) - 1)) #define ELF_TRUNC(a, b) ((a) & ~((b) - 1)) @@ -259,22 +264,30 @@ elf_check_header(Elf_Ehdr *eh) { if (memcmp(eh->e_ident, ELFMAG, SELFMAG) != 0 || - eh->e_ident[EI_CLASS] != ELFCLASS) + eh->e_ident[EI_CLASS] != ELFCLASS) { + DPRINTF("bad magic %#x%x%x", eh->e_ident[0], eh->e_ident[1], + eh->e_ident[2]); return ENOEXEC; + } switch (eh->e_machine) { ELFDEFNNAME(MACHDEP_ID_CASES) default: + DPRINTF("bad machine %#x", eh->e_machine); return ENOEXEC; } - if (ELF_EHDR_FLAGS_OK(eh) == 0) + if (ELF_EHDR_FLAGS_OK(eh) == 0) { + DPRINTF("bad flags %#x", eh->e_flags); return ENOEXEC; + } - if (eh->e_shnum > ELF_MAXSHNUM || eh->e_phnum > ELF_MAXPHNUM) + if (eh->e_shnum > ELF_MAXSHNUM || eh->e_phnum > ELF_MAXPHNUM) { + DPRINTF("bad shnum/phnum %#x/%#x", eh->e_shnum, eh->e_phnum); return ENOEXEC; + } return 0; } @@ -451,6 +464,7 @@ elf_load_interp(struct lwp *l, struct ex if ((error = elf_check_header(&eh)) != 0) goto bad; if (eh.e_type != ET_DYN || eh.e_phnum == 0) { + DPRINTF("bad interpreter type %#x", eh.e_type); error = ENOEXEC; goto bad; } @@ -495,6 +509,7 @@ elf_load_interp(struct lwp *l, struct ex } if (base_ph == NULL) { + DPRINTF("no interpreter loadable sections"); error = ENOEXEC; goto bad; } @@ -616,19 +631,25 @@ exec_elf_makecmds(struct lwp *l, struct struct elf_args *ap; bool is_dyn = false; - if (epp->ep_hdrvalid < sizeof(Elf_Ehdr)) + if (epp->ep_hdrvalid < sizeof(Elf_Ehdr)) { + DPRINTF("small header %#x", epp->ep_hdrvalid); return ENOEXEC; + } if ((error = elf_check_header(eh)) != 0) return error; if (eh->e_type == ET_DYN) /* PIE, and some libs have an entry point */ is_dyn = true; - else if (eh->e_type != ET_EXEC) + else if (eh->e_type != ET_EXEC) { + DPRINTF("bad type %#x", eh->e_type); return ENOEXEC; + } - if (eh->e_phnum == 0) + if (eh->e_phnum == 0) { + DPRINTF("no program headers"); return ENOEXEC; + } error = vn_marktext(epp->ep_vp); if (error) @@ -652,6 +673,8 @@ exec_elf_makecmds(struct lwp *l, struct pp = &ph[i]; if (pp->p_type == PT_INTERP) { if (pp->p_filesz < 2 || pp->p_filesz > MAXPATHLEN) { + DPRINTF("bad interpreter namelen %#jx", + (uintmax_t)pp->p_filesz); error = ENOEXEC; goto bad; } @@ -661,6 +684,7 @@ exec_elf_makecmds(struct lwp *l, struct goto bad; /* Ensure interp is NUL-terminated and of the expected length */ if (strnlen(interp, pp->p_filesz) != pp->p_filesz - 1) { + DPRINTF("bad interpreter name"); error = ENOEXEC; goto bad; } @@ -746,6 +770,7 @@ exec_elf_makecmds(struct lwp *l, struct if (epp->ep_vmcmds.evs_used == 0) { /* No VMCMD; there was no PT_LOAD section, or those * sections were empty */ + DPRINTF("no vmcommands"); error = ENOEXEC; goto bad; } @@ -769,6 +794,7 @@ exec_elf_makecmds(struct lwp *l, struct } if (epp->ep_vmcmds.evs_used == nused) { /* elf_load_interp() has not set up any new VMCMD */ + DPRINTF("no vmcommands for interpreter"); error = ENOEXEC; goto bad; } @@ -839,8 +865,10 @@ netbsd_elf_signature(struct lwp *l, stru #endif epp->ep_pax_flags = 0; - if (eh->e_shnum > ELF_MAXSHNUM || eh->e_shnum == 0) + if (eh->e_shnum > ELF_MAXSHNUM || eh->e_shnum == 0) { + DPRINTF("no signature %#x", eh->e_shnum); return ENOEXEC; + } shsize = eh->e_shnum * sizeof(Elf_Shdr); sh = kmem_alloc(shsize, KM_SLEEP); @@ -1004,6 +1032,10 @@ bad: kmem_free(np, ELF_MAXNOTESIZE); error = isnetbsd ? 0 : ENOEXEC; +#ifdef DEBUG_ELF + if (error) + DPRINTF("not netbsd"); +#endif out: kmem_free(sh, shsize); return error;