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

Reply via email to