From nobody Mon Feb 26 22:34:06 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4TkFlf2H9hz5BpCC; Mon, 26 Feb 2024 22:34:06 +0000 (UTC) (envelope-from git@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) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4TkFlf1nQ7z4Ptv; Mon, 26 Feb 2024 22:34:06 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1708986846; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=eFB4yk8Oi5Be9j18J0oOvvu2nSTGfIbiHKU8RMrpLmY=; b=Y2VyNy2fMQc2dZqRNgkhSB9LN3oCKI9B7uPnxL0hpuqINlr0hRhetHEGtJXH2q1trgvEyP 21PdTx7kDAHJwcOTMYNILvYtk/0g+dG20mp6NVF6gvZQsquJZ7Jdbsh6oG5Z/by9JIE0x9 uNcC3ZDNQm9TqHM4OiAxCbSMFSrCK2987/hUE++9mUdCcY6tiAnVIzb7RBUsW0baJp89eU m+buK+fDwJczHM2+K5yBZHlBzSmm3Vpm4ZT4IpzpnXmpstRi6uhhFqGSjZ0y6jUsg0RwGi 9O00Zpqy9IjbN3/PW5DAH5u9Bd+83bgP7LEdm/t2P73oS+FzIvKQaJFCLSDMOw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1708986846; a=rsa-sha256; cv=none; b=wd60duVvYwckOMrsplKGfgoT6UZTIj4KcvvWgxu8HDMdfWhsg8UAbyb9OFZeZXlF4kIWyU Eqf5/oiouSsPVSmwsWAYqOmcWEqyZAcPKrbWH7DBjny1dfdYZ26JJoj9QmiEAMqVXJZY61 d08qoPWR9Qnn7u1D2GmfntdBkMcImm/h6Uq3XwKm8Sszb2STu770swoOl4CHTZw8NL6MPJ faTjfaiMw0yLAWAKCIiLIZknmDtyC+EPkZYX7d1xZUt+5xro91vMVK9w5AUf2ukszrL3Hz 2FlWfzN+7oZL5D6Ig7SJpO/gu/PTY3lSnkwcNF8swmsixyjRVim1Gzy9IqPvVg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1708986846; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=eFB4yk8Oi5Be9j18J0oOvvu2nSTGfIbiHKU8RMrpLmY=; b=wloEG3PV/6oR6qyyzuyL9V5XZpBxpKwiS/z6IIg7tS+2xucIsS/YXgdePtM4Cg+zET3NnQ exEZ43Vb6Omx1n0AuXQyyYLCtv4oE+kXqWFk5qxpR75JdRBI2JOYkubeOF8TZpAtprYJTu 9boE+KQJf8K927VRqZvxfrMbJIGaunnA0mYtLJ268yYdzsX5gkRaB5t0mFTP20Qpw6zeRH gsm6UIZ7rQoQ/Sy8se7nZOQU8Vuk083x6E/uQJfqh0Ir2BTcAqz07DgAeFfieryjqfbrNE r7QvF+SpKDPpyczApX8hIsKaTTY05Hs7uJPuzOUnPjHKz1z72e/mcfvqc2B6Qw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4TkFlf0s5LzmNF; Mon, 26 Feb 2024 22:34:06 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 41QMY6D3043393; Mon, 26 Feb 2024 22:34:06 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 41QMY6cS043390; Mon, 26 Feb 2024 22:34:06 GMT (envelope-from git) Date: Mon, 26 Feb 2024 22:34:06 GMT Message-Id: <202402262234.41QMY6cS043390@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Stefan =?utf-8?Q?E=C3=9Fer?= Subject: git: 7b77d37a561b - main - rtld-elf: support either byte-order of hints file List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: se X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 7b77d37a561b47db093a2528b8032dbfe5791698 Auto-Submitted: auto-generated The branch main has been updated by se: URL: https://cgit.FreeBSD.org/src/commit/?id=7b77d37a561b47db093a2528b8032dbfe5791698 commit 7b77d37a561b47db093a2528b8032dbfe5791698 Author: Stefan Eßer AuthorDate: 2024-02-26 22:18:12 +0000 Commit: Stefan Eßer CommitDate: 2024-02-26 22:18:12 +0000 rtld-elf: support either byte-order of hints file Accept either little-endian or big-endian representation of the ELF hints magic number in the header of a hints file and convert the parameters to the native byte-order of the repsective system. This is a pre-requisite for a planned change to always write the byte order in little-endian format on all architectures. The only relvant architecture that uses big-endian data is powerpc64, and it is not likely that new architectures will choose that representation of data in memory. When all supported architectures use little-endian data in the hints file, the byte swap logic can be enabled for big-endian CPUs at compile time. Up to that point, there is a very small run-time penalty that is paid on all systems to check the byte-order of the hints file and to provide the option to byte-swap the parameters read from the hints file header. This commit contains the changes from review D44080 (which had been split off from this patch for easier review), Reviewed by: kib MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D44053 --- libexec/rtld-elf/rtld.c | 76 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 30ed48b5c615..4b6d19104343 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -2050,6 +2050,9 @@ find_symdef(unsigned long symnum, const Obj_Entry *refobj, return (def); } +/* Convert between native byte order and forced little resp. big endian. */ +#define COND_SWAP(n) (is_le ? le32toh(n) : be32toh(n)) + /* * Return the search path from the ldconfig hints file, reading it if * necessary. If nostdlib is true, then the default search paths are @@ -2073,6 +2076,12 @@ gethints(bool nostdlib) int fd; size_t flen; uint32_t dl; + uint32_t magic; /* Magic number */ + uint32_t version; /* File version (1) */ + uint32_t strtab; /* Offset of string table in file */ + uint32_t dirlist; /* Offset of directory list in string table */ + uint32_t dirlistlen; /* strlen(dirlist) */ + bool is_le; bool skip; /* First call, read the hints file */ @@ -2080,8 +2089,10 @@ gethints(bool nostdlib) /* Keep from trying again in case the hints file is bad. */ hints = ""; - if ((fd = open(ld_elf_hints_path, O_RDONLY | O_CLOEXEC)) == -1) + if ((fd = open(ld_elf_hints_path, O_RDONLY | O_CLOEXEC)) == -1) { + dbg("failed to open hints file \"%s\"", ld_elf_hints_path); return (NULL); + } /* * Check of hdr.dirlistlen value against type limit @@ -2089,29 +2100,62 @@ gethints(bool nostdlib) * paranoia leads to checks that dirlist is fully * contained in the file range. */ - if (read(fd, &hdr, sizeof hdr) != sizeof hdr || - hdr.magic != ELFHINTS_MAGIC || - hdr.version != 1 || hdr.dirlistlen > UINT_MAX / 2 || - fstat(fd, &hint_stat) == -1) { + if (read(fd, &hdr, sizeof hdr) != sizeof hdr) { + dbg("failed to read %lu bytes from hints file \"%s\"", + (u_long)sizeof hdr, ld_elf_hints_path); cleanup1: close(fd); hdr.dirlistlen = 0; return (NULL); } - dl = hdr.strtab; - if (dl + hdr.dirlist < dl) + is_le = /*le32toh(1) == 1 || */ hdr.magic == ELFHINTS_MAGIC; + magic = COND_SWAP(hdr.magic); + version = COND_SWAP(hdr.version); + strtab = COND_SWAP(hdr.strtab); + dirlist = COND_SWAP(hdr.dirlist); + dirlistlen = COND_SWAP(hdr.dirlistlen); + if (magic != ELFHINTS_MAGIC) { + dbg("invalid magic number %#08x (expected: %#08x)", + magic, ELFHINTS_MAGIC); goto cleanup1; - dl += hdr.dirlist; - if (dl + hdr.dirlistlen < dl) + } + if (version != 1) { + dbg("hints file version %d (expected: 1)", version); goto cleanup1; - dl += hdr.dirlistlen; - if (dl > hint_stat.st_size) + } + if (dirlistlen > UINT_MAX / 2) { + dbg("directory list is to long: %d > %d", + dirlistlen, UINT_MAX / 2); goto cleanup1; - p = xmalloc(hdr.dirlistlen + 1); - if (pread(fd, p, hdr.dirlistlen + 1, - hdr.strtab + hdr.dirlist) != (ssize_t)hdr.dirlistlen + 1 || - p[hdr.dirlistlen] != '\0') { + } + if (fstat(fd, &hint_stat) == -1) { + dbg("failed to find length of hints file \"%s\"", + ld_elf_hints_path); + goto cleanup1; + } + dl = strtab; + if (dl + dirlist < dl) { + dbg("invalid string table position %d", dl); + goto cleanup1; + } + dl += dirlist; + if (dl + dirlistlen < dl) { + dbg("invalid directory list offset %d", dirlist); + goto cleanup1; + } + dl += dirlistlen; + if (dl > hint_stat.st_size) { + dbg("hints file \"%s\" is truncated (%d vs. %jd bytes)", + ld_elf_hints_path, dl, (uintmax_t)hint_stat.st_size); + goto cleanup1; + } + p = xmalloc(dirlistlen + 1); + if (pread(fd, p, dirlistlen + 1, + strtab + dirlist) != (ssize_t)dirlistlen + 1 || + p[dirlistlen] != '\0') { free(p); + dbg("failed to read %d bytes starting at %d from hints file \"%s\"", + dirlistlen + 1, strtab + dirlist, ld_elf_hints_path); goto cleanup1; } hints = p; @@ -2174,7 +2218,7 @@ cleanup1: */ fndx = 0; fcount = 0; - filtered_path = xmalloc(hdr.dirlistlen + 1); + filtered_path = xmalloc(dirlistlen + 1); hintpath = &hintinfo->dls_serpath[0]; for (hintndx = 0; hintndx < hmeta.dls_cnt; hintndx++, hintpath++) { skip = false;