Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Jan 2020 10:00:24 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r356548 - head/libexec/rtld-elf
Message-ID:  <202001091000.009A0Ofo068419@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Thu Jan  9 10:00:24 2020
New Revision: 356548
URL: https://svnweb.freebsd.org/changeset/base/356548

Log:
  Resolve relative argv0 for direct exec mode to absolute path for AT_EXECPATH.
  
  We know the binary relative name and can reliably calculate cwd path.
  Because realpath(3) was already linked into ld-elf.so.1, reuse it
  there to resolve dots and dotdots making the path more canonical.
  
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week
  Differential revision:	https://reviews.freebsd.org/D23014

Modified:
  head/libexec/rtld-elf/rtld.c

Modified: head/libexec/rtld-elf/rtld.c
==============================================================================
--- head/libexec/rtld-elf/rtld.c	Thu Jan  9 09:47:23 2020	(r356547)
+++ head/libexec/rtld-elf/rtld.c	Thu Jan  9 10:00:24 2020	(r356548)
@@ -5513,9 +5513,12 @@ static int
 open_binary_fd(const char *argv0, bool search_in_path,
     const char **binpath_res)
 {
-	char *pathenv, *pe, *binpath;
+	char *abspath, *absres, *binpath, *pathenv, *pe, *res1;
+	const char *res;
 	int fd;
 
+	binpath = NULL;
+	res = NULL;
 	if (search_in_path && strchr(argv0, '/') == NULL) {
 		binpath = xmalloc(PATH_MAX);
 		pathenv = getenv("PATH");
@@ -5540,20 +5543,45 @@ open_binary_fd(const char *argv0, bool search_in_path,
 				continue;
 			fd = open(binpath, O_RDONLY | O_CLOEXEC | O_VERIFY);
 			if (fd != -1 || errno != ENOENT) {
-				*binpath_res = binpath;
+				res = binpath;
 				break;
 			}
 		}
 		free(pathenv);
 	} else {
 		fd = open(argv0, O_RDONLY | O_CLOEXEC | O_VERIFY);
-		*binpath_res = argv0;
+		res = argv0;
 	}
-	/* XXXKIB Use getcwd() to resolve relative binpath to absolute. */
 
 	if (fd == -1) {
 		_rtld_error("Cannot open %s: %s", argv0, rtld_strerror(errno));
 		rtld_die();
+	}
+	if (res != NULL && res[0] != '/') {
+		abspath = getcwd(NULL, 0);
+		if (abspath != NULL) {
+			res1 = xmalloc(PATH_MAX);
+			if (realpath(res, res1) != NULL) {
+				if (res != argv0)
+					free(__DECONST(char *, res));
+				res = res1;
+			} else {
+				free(res1);
+			}
+			absres = xmalloc(strlen(abspath) +
+			    strlen(res) + 2);
+			strcpy(absres, abspath);
+			strcat(absres, "/");
+			strcat(absres, res);
+			free(abspath);
+			if (res != argv0)
+				free(__DECONST(char *, res));
+			*binpath_res = absres;
+		} else {
+			*binpath_res = res;
+		}
+	} else {
+		*binpath_res = res;
 	}
 	return (fd);
 }



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