From nobody Thu Oct 30 23:52:38 2025 X-Original-To: dev-commits-src-branches@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 4cyLWp74P8z6FnR5; Thu, 30 Oct 2025 23:52:38 +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 "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4cyLWp3txHz3cvQ; Thu, 30 Oct 2025 23:52:38 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1761868358; 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=OLRehenoAP4Hjx8A0q1C7BE1RtfstvdPK5NFt8VeFNc=; b=FFGafKaoy9Y+3UvD4navqqBNj6V+CdGYSj2JG3q9g4kRzWYlptLj7kXDgOrs0duXstJ7u2 74Z6a9iyNJYYLeAuojTol25DckvmJWKioCKUS2OucnuJvT12M5ML7s/MWIBGsbc9RldQ8b +b9joNUrpcwoJI4drhiBtpnOHjHjctKsBGgfNc9HpIhi2UyzYeorQJqLnoNbCUwgM8wx+/ i8X6MC/ryMohyrVfJZj+XFuJrgcCoAG0yl640OIG7n/gOBLnF+w3CHbyFucs1NfU/TNI2o vkHpZA51k4eOk+tE9ibz0h8g7c6AbqzPyG9OYvUTyt3PLKaF8vW+r+Y7WHgkFw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1761868358; 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=OLRehenoAP4Hjx8A0q1C7BE1RtfstvdPK5NFt8VeFNc=; b=g4WhA4Qo5xEK8dfyOhrqignBFsCQUnIBeZPfY/T7nCVE2TQjNf3y1x6Z6Hw6JK+Lh3Sg7Y /jpmxiMOFBgHXIQTP1xnKl6zyJzWyRevQ2uhE9diJeWiox9nQeDbxQOnwj1aMmozajjPLW p6lVtyxQdCp0KqEcwGTwv3iqo+7g9y8efUugWEesFhUI+7L9LaWSZ7Tj4RaZ6DPdpfpMPJ tyMwI1Uq0NhKCfNkU5q9JGn/Mb/d09XKyyrjweV+9VjYlMAcUdjx3zsdx8SAzTpLjvlQh1 n6oN05i0BQ+hWkM/r7bDI/6QexKnFU8hmMPjCoAeymJhGBJSUbggjCiSvfMFCQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1761868358; a=rsa-sha256; cv=none; b=SSD5mjCAYERggLTjT7u1BX3VBMkWaqHAlgTQA7JsbDWB+hOPi/Bb2lN7JZz0NIsQDJzEXi 8emBcFYL0CpTNcSF6uvK20sOx8iCyVYg5XdMx+GHTkp5lz7RpZP94ikTgpp784yBKQ21Tr jHpmDf9iKyqMWcVdsiBJ4Gr+gdvZYsGuPr2pl226peY04JAB5UHabtYVB40rr5WB4zvKYQ W57OPzIxt8WZQYf5CvaeeWF8mYeLP1G+75JbEKQq/hYorSt1KK7heUuA9hDK8aQGFTnjdL +usGZR69uJx6NUj2/7jttdIN0yvRPIAA543IqnGJu1sSDdOentq3txfwF9TI5A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none 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 4cyLWp3SvnzlNG; Thu, 30 Oct 2025 23:52:38 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 59UNqci7088477; Thu, 30 Oct 2025 23:52:38 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 59UNqcjw088474; Thu, 30 Oct 2025 23:52:38 GMT (envelope-from git) Date: Thu, 30 Oct 2025 23:52:38 GMT Message-Id: <202510302352.59UNqcjw088474@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Colin Percival Subject: git: 38c42ca57ba5 - releng/15.0 - realpath: Report correct path on failure List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: cperciva X-Git-Repository: src X-Git-Refname: refs/heads/releng/15.0 X-Git-Reftype: branch X-Git-Commit: 38c42ca57ba5e94e7fe086f315f11d7583f54818 Auto-Submitted: auto-generated The branch releng/15.0 has been updated by cperciva: URL: https://cgit.FreeBSD.org/src/commit/?id=38c42ca57ba5e94e7fe086f315f11d7583f54818 commit 38c42ca57ba5e94e7fe086f315f11d7583f54818 Author: Dag-Erling Smørgrav AuthorDate: 2025-10-13 11:53:22 +0000 Commit: Colin Percival CommitDate: 2025-10-30 23:49:49 +0000 realpath: Report correct path on failure If lstat() fails with EACCES or ENOTDIR, the path we need to return in the caller-provided buffer is that of the parent directory (which is either unreadable or not a directory; the latter can only happen in the case of a race) rather than that of the child we attempted to stat. Approved by: re (cperciva) Sponsored by: Klara, Inc. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D53025 (cherry picked from commit 1406de21e176d8700240ac9e473df007cd41eec1) (cherry picked from commit 6c9b25246d4408eced73886d0b58feef7bff25c6) --- lib/libc/stdlib/realpath.c | 14 ++++++++++++-- lib/libc/tests/gen/realpath2_test.c | 11 ++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/libc/stdlib/realpath.c b/lib/libc/stdlib/realpath.c index 4c52b73319ab..18f29e95ee6b 100644 --- a/lib/libc/stdlib/realpath.c +++ b/lib/libc/stdlib/realpath.c @@ -49,7 +49,7 @@ realpath1(const char *path, char *resolved) { struct stat sb; char *p, *q; - size_t left_len, resolved_len, next_token_len; + size_t left_len, prev_len, resolved_len, next_token_len; unsigned symlinks; ssize_t slen; char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; @@ -98,6 +98,7 @@ realpath1(const char *path, char *resolved) left_len = 0; } + prev_len = resolved_len; if (resolved[resolved_len - 1] != '/') { if (resolved_len + 1 >= PATH_MAX) { errno = ENAMETOOLONG; @@ -133,8 +134,17 @@ realpath1(const char *path, char *resolved) errno = ENAMETOOLONG; return (NULL); } - if (lstat(resolved, &sb) != 0) + if (lstat(resolved, &sb) != 0) { + /* + * EACCES means the parent directory is not + * readable, while ENOTDIR means the parent + * directory is not a directory. Rewind the path + * to correctly indicate where the error lies. + */ + if (errno == EACCES || errno == ENOTDIR) + resolved[prev_len] = '\0'; return (NULL); + } if (S_ISLNK(sb.st_mode)) { if (symlinks++ > MAXSYMLINKS) { errno = ELOOP; diff --git a/lib/libc/tests/gen/realpath2_test.c b/lib/libc/tests/gen/realpath2_test.c index b8f951d9b10f..431df8721ae0 100644 --- a/lib/libc/tests/gen/realpath2_test.c +++ b/lib/libc/tests/gen/realpath2_test.c @@ -158,15 +158,8 @@ ATF_TC_BODY(realpath_partial, tc) ATF_REQUIRE_EQ(0, chmod("foo", 000)); ATF_REQUIRE_ERRNO(EACCES, realpath("foo/bar/baz", resb) == NULL); len = strnlen(resb, sizeof(resb)); - ATF_REQUIRE(len > 8 && len < sizeof(resb)); - /* - * This is arguably wrong. The problem is not with bar, but with - * foo. However, since foo exists and is a directory and the only - * reliable way to detect whether a directory is readable is to - * attempt to read it, we do not detect the problem until we try - * to access bar. - */ - ATF_REQUIRE_STREQ("/foo/bar", resb + len - 8); + ATF_REQUIRE(len > 4 && len < sizeof(resb)); + ATF_REQUIRE_STREQ("/foo", resb + len - 4); /* scenario 6: not a directory */ ATF_REQUIRE_EQ(0, close(creat("bar", 0644)));