Author: kib
Date: Tue May 23 10:00:52 2017
New Revision: 318739
URL: https://svnweb.freebsd.org/changeset/base/318739

Log:
  For ld.so direct execution mode, implement -p option: search for the
  binary in $PATH.
  
  Sponsored by: The FreeBSD Foundation
  MFC after:    2 weeks
  Differential revision:        https://reviews.freebsd.org/D10790

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

Modified: head/libexec/rtld-elf/rtld.c
==============================================================================
--- head/libexec/rtld-elf/rtld.c        Tue May 23 09:32:26 2017        
(r318738)
+++ head/libexec/rtld-elf/rtld.c        Tue May 23 10:00:52 2017        
(r318739)
@@ -120,6 +120,7 @@ static void objlist_push_head(Objlist *,
 static void objlist_push_tail(Objlist *, Obj_Entry *);
 static void objlist_put_after(Objlist *, Obj_Entry *, Obj_Entry *);
 static void objlist_remove(Objlist *, Obj_Entry *);
+static int open_binary_fd(const char *argv0, bool search_in_path);
 static int parse_args(char* argv[], int argc, bool *use_pathp, int *fdp);
 static int parse_integer(const char *);
 static void *path_enumerate(const char *, path_enum_proc, void *);
@@ -439,12 +440,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_
                argv0 = argv[rtld_argc];
                explicit_fd = (fd != -1);
                if (!explicit_fd)
-                   fd = open(argv0, O_RDONLY | O_CLOEXEC | O_VERIFY);
-               if (fd == -1) {
-                   rtld_printf("Opening %s: %s\n", argv0,
-                     rtld_strerror(errno));
-                   rtld_die();
-               }
+                   fd = open_binary_fd(argv0, search_in_path);
                if (fstat(fd, &st) == -1) {
                    _rtld_error("failed to fstat FD %d (%s): %s", fd,
                      explicit_fd ? "user-provided descriptor" : argv0,
@@ -5280,6 +5276,52 @@ symlook_init_from_req(SymLook *dst, cons
        dst->lockstate = src->lockstate;
 }
 
+static int
+open_binary_fd(const char *argv0, bool search_in_path)
+{
+       char *pathenv, *pe, binpath[PATH_MAX];
+       int fd;
+
+       if (search_in_path && strchr(argv0, '/') == NULL) {
+               pathenv = getenv("PATH");
+               if (pathenv == NULL) {
+                       rtld_printf("-p and no PATH environment variable\n");
+                       rtld_die();
+               }
+               pathenv = strdup(pathenv);
+               if (pathenv == NULL) {
+                       rtld_printf("Cannot allocate memory\n");
+                       rtld_die();
+               }
+               fd = -1;
+               errno = ENOENT;
+               while ((pe = strsep(&pathenv, ":")) != NULL) {
+                       if (strlcpy(binpath, pe, sizeof(binpath)) >
+                           sizeof(binpath))
+                               continue;
+                       if (binpath[0] != '\0' &&
+                           strlcat(binpath, "/", sizeof(binpath)) >
+                           sizeof(binpath))
+                               continue;
+                       if (strlcat(binpath, argv0, sizeof(binpath)) >
+                           sizeof(binpath))
+                               continue;
+                       fd = open(binpath, O_RDONLY | O_CLOEXEC | O_VERIFY);
+                       if (fd != -1 || errno != ENOENT)
+                               break;
+               }
+               free(pathenv);
+       } else {
+               fd = open(argv0, O_RDONLY | O_CLOEXEC | O_VERIFY);
+       }
+
+       if (fd == -1) {
+               rtld_printf("Opening %s: %s\n", argv0,
+                   rtld_strerror(errno));
+               rtld_die();
+       }
+       return (fd);
+}
 
 /*
  * Parse a set of command-line arguments.
@@ -5341,10 +5383,8 @@ parse_args(char* argv[], int argc, bool 
                        }
                        *fdp = fd;
                        break;
-                       /* TODO:
                        } else if (opt == 'p') {
                                *use_pathp = true;
-                       */
                        } else {
                                rtld_printf("invalid argument: '%s'\n", arg);
                                print_usage(argv[0]);
@@ -5391,7 +5431,7 @@ print_usage(const char *argv0)
                "\n"
                "Options:\n"
                "  -h        Display this help message\n"
-               /* TODO: "  -p        Search in PATH for named binary\n" */
+               "  -p        Search in PATH for named binary\n"
                "  -f <FD>   Execute <FD> instead of searching for <binary>\n"
                "  --        End of RTLD options\n"
                "  <binary>  Name of process to execute\n"
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to