Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 May 2019 20:27:46 +0000 (UTC)
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r347575 - stable/12/sys/kern
Message-ID:  <201905142027.x4EKRkY1069144@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trasz
Date: Tue May 14 20:27:45 2019
New Revision: 347575
URL: https://svnweb.freebsd.org/changeset/base/347575

Log:
  MFC r346030:
  
  Refactor ELF interpreter loading into a separate function.
  
  Sponsored by:	DARPA, AFRL

Modified:
  stable/12/sys/kern/imgact_elf.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/kern/imgact_elf.c
==============================================================================
--- stable/12/sys/kern/imgact_elf.c	Tue May 14 20:26:05 2019	(r347574)
+++ stable/12/sys/kern/imgact_elf.c	Tue May 14 20:27:45 2019	(r347575)
@@ -946,6 +946,41 @@ __elfN(get_interp)(struct image_params *imgp, const El
 	return (0);
 }
 
+static int
+__elfN(load_interp)(struct image_params *imgp, const Elf_Brandinfo *brand_info,
+    const char *interp, u_long *addr, u_long *entry)
+{
+	char *path;
+	int error;
+
+	if (brand_info->emul_path != NULL &&
+	    brand_info->emul_path[0] != '\0') {
+		path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
+		snprintf(path, MAXPATHLEN, "%s%s",
+		    brand_info->emul_path, interp);
+		error = __elfN(load_file)(imgp->proc, path, addr, entry);
+		free(path, M_TEMP);
+		if (error == 0)
+			return (0);
+	}
+
+	if (brand_info->interp_newpath != NULL &&
+	    (brand_info->interp_path == NULL ||
+	    strcmp(interp, brand_info->interp_path) == 0)) {
+		error = __elfN(load_file)(imgp->proc,
+		    brand_info->interp_newpath, addr, entry);
+		if (error == 0)
+			return (0);
+	}
+
+	error = __elfN(load_file)(imgp->proc, interp, addr, entry);
+	if (error == 0)
+		return (0);
+
+	uprintf("ELF interpreter %s not found, error %d\n", interp, error);
+	return (error);
+}
+
 /*
  * Impossible et_dyn_addr initial value indicating that the real base
  * must be calculated later with some randomization applied.
@@ -961,8 +996,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 	Elf_Auxargs *elf_auxargs;
 	struct vmspace *vmspace;
 	vm_map_t map;
-	const char *newinterp;
-	char *interp, *path;
+	char *interp;
 	Elf_Brandinfo *brand_info;
 	struct sysentvec *sv;
 	vm_prot_t prot;
@@ -971,7 +1005,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 	uint32_t fctl0;
 	int32_t osrel;
 	bool free_interp;
-	int error, i, n, have_interp;
+	int error, i, n;
 
 	hdr = (const Elf_Ehdr *)imgp->image_header;
 
@@ -1007,7 +1041,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 	osrel = 0;
 	fctl0 = 0;
 	entry = proghdr = 0;
-	newinterp = interp = NULL;
+	interp = NULL;
 	free_interp = false;
 	td = curthread;
 	maxalign = PAGE_SIZE;
@@ -1075,8 +1109,6 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 				et_dyn_addr = ET_DYN_LOAD_ADDR;
 		}
 	}
-	if (interp != NULL && brand_info->interp_newpath != NULL)
-		newinterp = brand_info->interp_newpath;
 
 	/*
 	 * Avoid a possible deadlock if the current address space is destroyed
@@ -1201,7 +1233,6 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 	imgp->entry_addr = entry;
 
 	if (interp != NULL) {
-		have_interp = FALSE;
 		VOP_UNLOCK(imgp->vp, 0);
 		if ((map->flags & MAP_ASLR) != 0) {
 			/* Assume that interpeter fits into 1/4 of AS */
@@ -1210,35 +1241,11 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 			addr = __CONCAT(rnd_, __elfN(base))(map, addr,
 			    maxv1, PAGE_SIZE);
 		}
-		if (brand_info->emul_path != NULL &&
-		    brand_info->emul_path[0] != '\0') {
-			path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
-			snprintf(path, MAXPATHLEN, "%s%s",
-			    brand_info->emul_path, interp);
-			error = __elfN(load_file)(imgp->proc, path, &addr,
-			    &imgp->entry_addr);
-			free(path, M_TEMP);
-			if (error == 0)
-				have_interp = TRUE;
-		}
-		if (!have_interp && newinterp != NULL &&
-		    (brand_info->interp_path == NULL ||
-		    strcmp(interp, brand_info->interp_path) == 0)) {
-			error = __elfN(load_file)(imgp->proc, newinterp, &addr,
-			    &imgp->entry_addr);
-			if (error == 0)
-				have_interp = TRUE;
-		}
-		if (!have_interp) {
-			error = __elfN(load_file)(imgp->proc, interp, &addr,
-			    &imgp->entry_addr);
-		}
+		error = __elfN(load_interp)(imgp, brand_info, interp, &addr,
+		    &imgp->entry_addr);
 		vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
-		if (error != 0) {
-			uprintf("ELF interpreter %s not found, error %d\n",
-			    interp, error);
+		if (error != 0)
 			goto ret;
-		}
 	} else
 		addr = et_dyn_addr;
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905142027.x4EKRkY1069144>