Module Name: src Committed By: maxv Date: Wed Feb 19 15:23:20 UTC 2014
Modified Files: src/sys/kern: exec_elf.c kern_exec.c Log Message: We need VMCMDs for a binary and its interpreter, so make sure we have at least one VMCMD. This also prevents the kernel from using an uninitialized pointer as entry point for the execution. >From me and Christos ok christos@ To generate a diff of this commit: cvs rdiff -u -r1.58 -r1.59 src/sys/kern/exec_elf.c cvs rdiff -u -r1.376 -r1.377 src/sys/kern/kern_exec.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.58 src/sys/kern/exec_elf.c:1.59 --- src/sys/kern/exec_elf.c:1.58 Sun Feb 16 17:46:36 2014 +++ src/sys/kern/exec_elf.c Wed Feb 19 15:23:20 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: exec_elf.c,v 1.58 2014/02/16 17:46:36 maxv Exp $ */ +/* $NetBSD: exec_elf.c,v 1.59 2014/02/19 15:23:20 maxv Exp $ */ /*- * Copyright (c) 1994, 2000, 2005 The NetBSD Foundation, Inc. @@ -57,7 +57,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.58 2014/02/16 17:46:36 maxv Exp $"); +__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.59 2014/02/19 15:23:20 maxv Exp $"); #ifdef _KERNEL_OPT #include "opt_pax.h" @@ -796,6 +796,14 @@ exec_elf_makecmds(struct lwp *l, struct break; } } + + if (epp->ep_vmcmds.evs_cmds == NULL) { + /* No VMCMD; there was no PT_LOAD section, or those + * sections were empty */ + error = ENOEXEC; + goto bad; + } + if (interp || (epp->ep_flags & EXEC_FORCEAUX) != 0) { ap = kmem_alloc(sizeof(*ap), KM_SLEEP); ap->arg_interp = (vaddr_t)NULL; @@ -811,7 +819,7 @@ exec_elf_makecmds(struct lwp *l, struct * its interpreter */ if (interp) { - int j = epp->ep_vmcmds.evs_used; + int nused = epp->ep_vmcmds.evs_used; u_long interp_offset = 0; if ((error = elf_load_file(l, epp, interp, @@ -819,7 +827,14 @@ exec_elf_makecmds(struct lwp *l, struct kmem_free(ap, sizeof(*ap)); goto bad; } - ap->arg_interp = epp->ep_vmcmds.evs_cmds[j].ev_addr; + if (epp->ep_vmcmds.evs_used == nused) { + /* elf_load_file() has not set up any new VMCMD */ + kmem_free(ap, sizeof(*ap)); + error = ENOEXEC; + goto bad; + } + + ap->arg_interp = epp->ep_vmcmds.evs_cmds[nused].ev_addr; epp->ep_entry = ap->arg_interp + interp_offset; PNBUF_PUT(interp); } else Index: src/sys/kern/kern_exec.c diff -u src/sys/kern/kern_exec.c:1.376 src/sys/kern/kern_exec.c:1.377 --- src/sys/kern/kern_exec.c:1.376 Mon Feb 17 19:29:46 2014 +++ src/sys/kern/kern_exec.c Wed Feb 19 15:23:20 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_exec.c,v 1.376 2014/02/17 19:29:46 maxv Exp $ */ +/* $NetBSD: kern_exec.c,v 1.377 2014/02/19 15:23:20 maxv Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -59,7 +59,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.376 2014/02/17 19:29:46 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.377 2014/02/19 15:23:20 maxv Exp $"); #include "opt_exec.h" #include "opt_execfmt.h" @@ -658,8 +658,7 @@ execve_loadvm(struct lwp *l, const char data->ed_pack.ep_hdrvalid = 0; data->ed_pack.ep_emul_arg = NULL; data->ed_pack.ep_emul_arg_free = NULL; - data->ed_pack.ep_vmcmds.evs_cnt = 0; - data->ed_pack.ep_vmcmds.evs_used = 0; + memset(&data->ed_pack.ep_vmcmds, 0, sizeof(data->ed_pack.ep_vmcmds)); data->ed_pack.ep_vap = &data->ed_attr; data->ed_pack.ep_flags = 0; MD_TOPDOWN_INIT(&data->ed_pack);