Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Oct 2017 12:56:09 +0000 (UTC)
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r324953 - head/libexec/rtld-elf
Message-ID:  <201710241256.v9OCu9ie052150@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trasz
Date: Tue Oct 24 12:56:08 2017
New Revision: 324953
URL: https://svnweb.freebsd.org/changeset/base/324953

Log:
  Remove unneeded calls to access(2) from rtld(1); just call open(2) instead.
  The result looks like this:
  
  --- przed       2017-10-21 23:19:21.445034000 +0100
  +++ po  2017-10-21 23:18:50.031865000 +0100
  @@ -11,7 +11,6 @@ mmap(0x0,102,PROT_READ,MAP_PRIVATE,3,0x0)      = 343665418
   close(3)                                        = 0 (0x0)
   open("/usr/local/etc/libmap.d",O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC,0165) ERR#2 'No such file or directory'
   munmap(0x80067d000,102)                                 = 0 (0x0)
  -access("/usr/local/lib/libintl.so.8",F_OK)      = 0 (0x0)
   openat(AT_FDCWD,"/usr/local/lib/libintl.so.8",O_RDONLY|O_CLOEXEC|O_VERIFY,00) = 3 (0x3)
   fstat(3,{ mode=-rw-r--r-- ,inode=642560,size=55188,blksize=32768 }) = 0 (0x0)
   mmap(0x0,4096,PROT_READ,MAP_PRIVATE|MAP_PREFAULT_READ,3,0x0) = 34366541824 (0x80067d000)
  @@ -20,14 +19,13 @@ mmap(0x800877000,40960,PROT_READ|PROT_EXEC,MAP_PRIVATE
   mmap(0x800a81000,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_FIXED|MAP_PREFAULT_READ,3,0xa000) = 34370752512 (0x800a81000)
   munmap(0x80067d000,4096)                        = 0 (0x0)
   close(3)                                        = 0 (0x0)
  -access("/usr/local/lib/libc.so.7",F_OK)                 ERR#2 'No such file or directory'
  +openat(AT_FDCWD,"/usr/local/lib/libc.so.7",O_RDONLY|O_CLOEXEC|O_VERIFY,00) ERR#2 'No such file or directory'
   openat(AT_FDCWD,"/var/run/ld-elf.so.hints",O_RDONLY|O_CLOEXEC,00) = 3 (0x3)
   read(3,"Ehnt\^A\0\0\0\M^@\0\0\0\M-2\0\0"...,128) = 128 (0x80)
   fstat(3,{ mode=-r--r--r-- ,inode=970684,size=306,blksize=32768 }) = 0 (0x0)
   lseek(3,0x80,SEEK_SET)                          = 128 (0x80)
   read(3,"/lib:/usr/lib:/usr/lib/compat:/u"...,178) = 178 (0xb2)
   close(3)                                        = 0 (0x0)
  -access("/lib/libc.so.7",F_OK)                   = 0 (0x0)
   openat(AT_FDCWD,"/lib/libc.so.7",O_RDONLY|O_CLOEXEC|O_VERIFY,00) = 3 (0x3)
   fstat(3,{ mode=-r--r--r-- ,inode=1605239,size=1910320,blksize=32768 }) = 0 (0x0)
   mmap(0x0,4096,PROT_READ,MAP_PRIVATE|MAP_PREFAULT_READ,3,0x0) = 34366541824 (0x80067d000)
  
  Reviewed by:	kib
  MFC after:	2 weeks
  Sponsored by:	DARPA, AFRL
  Differential Revision:	https://reviews.freebsd.org/D12766

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

Modified: head/libexec/rtld-elf/rtld.c
==============================================================================
--- head/libexec/rtld-elf/rtld.c	Tue Oct 24 12:04:07 2017	(r324952)
+++ head/libexec/rtld-elf/rtld.c	Tue Oct 24 12:56:08 2017	(r324953)
@@ -138,7 +138,7 @@ static int rtld_dirname(const char *, char *);
 static int rtld_dirname_abs(const char *, char *);
 static void *rtld_dlopen(const char *name, int fd, int mode);
 static void rtld_exit(void);
-static char *search_library_path(const char *, const char *);
+static char *search_library_path(const char *, const char *, int *);
 static char *search_library_pathfds(const char *, const char *, int *);
 static const void **get_program_var_addr(const char *, RtldLockState *);
 static void set_program_var(const char *, const void *);
@@ -1620,52 +1620,52 @@ find_library(const char *xname, const Obj_Entry *refob
 	 * nodeflib.
 	 */
 	if (objgiven && refobj->rpath != NULL && ld_library_path_rpath) {
-		pathname = search_library_path(name, ld_library_path);
+		pathname = search_library_path(name, ld_library_path, fdp);
 		if (pathname != NULL)
 			return (pathname);
 		if (refobj != NULL) {
-			pathname = search_library_path(name, refobj->rpath);
+			pathname = search_library_path(name, refobj->rpath, fdp);
 			if (pathname != NULL)
 				return (pathname);
 		}
 		pathname = search_library_pathfds(name, ld_library_dirs, fdp);
 		if (pathname != NULL)
 			return (pathname);
-		pathname = search_library_path(name, gethints(false));
+		pathname = search_library_path(name, gethints(false), fdp);
 		if (pathname != NULL)
 			return (pathname);
-		pathname = search_library_path(name, ld_standard_library_path);
+		pathname = search_library_path(name, ld_standard_library_path, fdp);
 		if (pathname != NULL)
 			return (pathname);
 	} else {
 		nodeflib = objgiven ? refobj->z_nodeflib : false;
 		if (objgiven) {
-			pathname = search_library_path(name, refobj->rpath);
+			pathname = search_library_path(name, refobj->rpath, fdp);
 			if (pathname != NULL)
 				return (pathname);
 		}
 		if (objgiven && refobj->runpath == NULL && refobj != obj_main) {
-			pathname = search_library_path(name, obj_main->rpath);
+			pathname = search_library_path(name, obj_main->rpath, fdp);
 			if (pathname != NULL)
 				return (pathname);
 		}
-		pathname = search_library_path(name, ld_library_path);
+		pathname = search_library_path(name, ld_library_path, fdp);
 		if (pathname != NULL)
 			return (pathname);
 		if (objgiven) {
-			pathname = search_library_path(name, refobj->runpath);
+			pathname = search_library_path(name, refobj->runpath, fdp);
 			if (pathname != NULL)
 				return (pathname);
 		}
 		pathname = search_library_pathfds(name, ld_library_dirs, fdp);
 		if (pathname != NULL)
 			return (pathname);
-		pathname = search_library_path(name, gethints(nodeflib));
+		pathname = search_library_path(name, gethints(nodeflib), fdp);
 		if (pathname != NULL)
 			return (pathname);
 		if (objgiven && !nodeflib) {
 			pathname = search_library_path(name,
-			    ld_standard_library_path);
+			    ld_standard_library_path, fdp);
 			if (pathname != NULL)
 				return (pathname);
 		}
@@ -3022,12 +3022,14 @@ struct try_library_args {
     size_t	 namelen;
     char	*buffer;
     size_t	 buflen;
+    int		 fd;
 };
 
 static void *
 try_library_path(const char *dir, size_t dirlen, void *param)
 {
     struct try_library_args *arg;
+    int fd;
 
     arg = param;
     if (*dir == '/' || trust) {
@@ -3042,17 +3044,23 @@ try_library_path(const char *dir, size_t dirlen, void 
 	strcpy(pathname + dirlen + 1, arg->name);
 
 	dbg("  Trying \"%s\"", pathname);
-	if (access(pathname, F_OK) == 0) {		/* We found it */
+	fd = open(pathname, O_RDONLY | O_CLOEXEC | O_VERIFY);
+	if (fd >= 0) {
+	    dbg("  Opened \"%s\", fd %d", pathname, fd);
 	    pathname = xmalloc(dirlen + 1 + arg->namelen + 1);
 	    strcpy(pathname, arg->buffer);
+	    arg->fd = fd;
 	    return (pathname);
+	} else {
+	    dbg("  Failed to open \"%s\": %s",
+		pathname, rtld_strerror(errno));
 	}
     }
     return (NULL);
 }
 
 static char *
-search_library_path(const char *name, const char *path)
+search_library_path(const char *name, const char *path, int *fdp)
 {
     char *p;
     struct try_library_args arg;
@@ -3064,8 +3072,10 @@ search_library_path(const char *name, const char *path
     arg.namelen = strlen(name);
     arg.buffer = xmalloc(PATH_MAX);
     arg.buflen = PATH_MAX;
+    arg.fd = -1;
 
     p = path_enumerate(path, try_library_path, &arg);
+    *fdp = arg.fd;
 
     free(arg.buffer);
 



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