From owner-svn-src-all@freebsd.org Tue May 23 10:00:54 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 471C1D7A14B; Tue, 23 May 2017 10:00:54 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 22484123B; Tue, 23 May 2017 10:00:54 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v4NA0rUM040474; Tue, 23 May 2017 10:00:53 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v4NA0rQu040473; Tue, 23 May 2017 10:00:53 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201705231000.v4NA0rQu040473@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Tue, 23 May 2017 10:00:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r318739 - head/libexec/rtld-elf X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 May 2017 10:00:54 -0000 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 Execute instead of searching for \n" " -- End of RTLD options\n" " Name of process to execute\n"