From owner-svn-src-stable-12@freebsd.org Thu Jan 9 09:14:54 2020 Return-Path: Delivered-To: svn-src-stable-12@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id C722622E99B; Thu, 9 Jan 2020 09:14:54 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47tgRy4M9Cz3LSq; Thu, 9 Jan 2020 09:14: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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 90B8E26828; Thu, 9 Jan 2020 09:14: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 0099Es8c043757; Thu, 9 Jan 2020 09:14:54 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0099EsSn043756; Thu, 9 Jan 2020 09:14:54 GMT (envelope-from kib@FreeBSD.org) Message-Id: <202001090914.0099EsSn043756@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Thu, 9 Jan 2020 09:14:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r356544 - stable/12/libexec/rtld-elf X-SVN-Group: stable-12 X-SVN-Commit-Author: kib X-SVN-Commit-Paths: stable/12/libexec/rtld-elf X-SVN-Commit-Revision: 356544 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-12@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 12-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Jan 2020 09:14:54 -0000 Author: kib Date: Thu Jan 9 09:14:54 2020 New Revision: 356544 URL: https://svnweb.freebsd.org/changeset/base/356544 Log: MFC r356300, r356503: Fix AT_EXECPATH for direct exec mode. Modified: stable/12/libexec/rtld-elf/rtld.c Directory Properties: stable/12/ (props changed) Modified: stable/12/libexec/rtld-elf/rtld.c ============================================================================== --- stable/12/libexec/rtld-elf/rtld.c Thu Jan 9 08:29:31 2020 (r356543) +++ stable/12/libexec/rtld-elf/rtld.c Thu Jan 9 09:14:54 2020 (r356544) @@ -134,7 +134,8 @@ static void objlist_push_head(Objlist *, Obj_Entry *); 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 open_binary_fd(const char *argv0, bool search_in_path, + const char **binpath_res); 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, const char *, void *); @@ -379,7 +380,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entr struct stat st; Elf_Addr *argcp; char **argv, **env, **envp, *kexecpath, *library_path_rpath; - const char *argv0; + const char *argv0, *binpath; caddr_t imgentry; char buf[MAXPATHLEN]; int argc, fd, i, phnum, rtld_argc; @@ -441,8 +442,9 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entr rtld_argc = parse_args(argv, argc, &search_in_path, &fd); argv0 = argv[rtld_argc]; explicit_fd = (fd != -1); + binpath = NULL; if (!explicit_fd) - fd = open_binary_fd(argv0, search_in_path); + fd = open_binary_fd(argv0, search_in_path, &binpath); if (fstat(fd, &st) == -1) { _rtld_error("Failed to fstat FD %d (%s): %s", fd, explicit_fd ? "user-provided descriptor" : argv0, @@ -495,11 +497,24 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entr } while (*envp != NULL); aux = auxp = (Elf_Auxinfo *)envp; auxpf = (Elf_Auxinfo *)(envp + rtld_argc); + /* XXXKIB insert place for AT_EXECPATH if not present */ for (;; auxp++, auxpf++) { *auxp = *auxpf; if (auxp->a_type == AT_NULL) break; } + + /* Point AT_EXECPATH auxv and aux_info to the binary path. */ + if (binpath == NULL) { + aux_info[AT_EXECPATH] = NULL; + } else { + if (aux_info[AT_EXECPATH] == NULL) { + aux_info[AT_EXECPATH] = xmalloc(sizeof(Elf_Auxinfo)); + aux_info[AT_EXECPATH]->a_type = AT_EXECPATH; + } + aux_info[AT_EXECPATH]->a_un.a_ptr = __DECONST(void *, + binpath); + } } else { _rtld_error("No binary"); rtld_die(); @@ -5453,12 +5468,14 @@ symlook_init_from_req(SymLook *dst, const SymLook *src } static int -open_binary_fd(const char *argv0, bool search_in_path) +open_binary_fd(const char *argv0, bool search_in_path, + const char **binpath_res) { - char *pathenv, *pe, binpath[PATH_MAX]; + char *pathenv, *pe, *binpath; int fd; if (search_in_path && strchr(argv0, '/') == NULL) { + binpath = xmalloc(PATH_MAX); pathenv = getenv("PATH"); if (pathenv == NULL) { _rtld_error("-p and no PATH environment variable"); @@ -5472,24 +5489,25 @@ open_binary_fd(const char *argv0, bool search_in_path) fd = -1; errno = ENOENT; while ((pe = strsep(&pathenv, ":")) != NULL) { - if (strlcpy(binpath, pe, sizeof(binpath)) >= - sizeof(binpath)) + if (strlcpy(binpath, pe, PATH_MAX) >= PATH_MAX) continue; if (binpath[0] != '\0' && - strlcat(binpath, "/", sizeof(binpath)) >= - sizeof(binpath)) + strlcat(binpath, "/", PATH_MAX) >= PATH_MAX) continue; - if (strlcat(binpath, argv0, sizeof(binpath)) >= - sizeof(binpath)) + if (strlcat(binpath, argv0, PATH_MAX) >= PATH_MAX) continue; fd = open(binpath, O_RDONLY | O_CLOEXEC | O_VERIFY); - if (fd != -1 || errno != ENOENT) + if (fd != -1 || errno != ENOENT) { + *binpath_res = binpath; break; + } } free(pathenv); } else { fd = open(argv0, O_RDONLY | O_CLOEXEC | O_VERIFY); + *binpath_res = argv0; } + /* XXXKIB Use getcwd() to resolve relative binpath to absolute. */ if (fd == -1) { _rtld_error("Cannot open %s: %s", argv0, rtld_strerror(errno));