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);