From patchwork Sun Mar 18 19:44:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 26366 Received: (qmail 536 invoked by alias); 18 Mar 2018 19:45:01 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 342 invoked by uid 89); 18 Mar 2018 19:45:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS, SPF_NEUTRAL autolearn=ham version=3.3.2 spammy=H*r:sk:static-, H*RU:sk:static-, Hx-spam-relays-external:sk:static-, our X-HELO: hera.aquilenet.fr From: Samuel Thibault To: libc-alpha@sourceware.org Cc: Samuel Thibault Subject: [hurd,commited 1/5] hurd: Fix O_NOFOLLOW Date: Sun, 18 Mar 2018 20:44:47 +0100 Message-Id: <20180318194451.11862-2-samuel.thibault@ens-lyon.org> In-Reply-To: <20180318194451.11862-1-samuel.thibault@ens-lyon.org> References: <20180318194451.11862-1-samuel.thibault@ens-lyon.org> The error code documented by POSIX for opening a symlink with O_NOFOLLOW is ELOOP. Also, if the translator does not expose symlink as a symlink translator but as a S_IFLNK file, O_NOFOLLOW needs to return ELOOP too. * hurd/lookup-retry.c (__hurd_file_name_lookup_retry): Return ELOOP when opening a symlink with O_NOFOLLOW. --- ChangeLog | 2 ++ hurd/lookup-retry.c | 36 ++++++++++++++++++++---------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index af84374b68..82ddda54ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -62,6 +62,8 @@ 2018-03-18 Samuel Thibault * sysdeps/mach/hurd/cthreads.c: Include . + * hurd/lookup-retry.c (__hurd_file_name_lookup_retry): Return ELOOP + when opening a symlink with O_NOFOLLOW. 2018-03-17 Samuel Thibault diff --git a/hurd/lookup-retry.c b/hurd/lookup-retry.c index 319e9c0a4c..12b5c30962 100644 --- a/hurd/lookup-retry.c +++ b/hurd/lookup-retry.c @@ -127,7 +127,7 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port) { /* In Linux, O_NOFOLLOW means to reject symlinks. If we did an O_NOLINK lookup above and io_stat here to check - for S_IFLNK, a translator like firmlink could easily + for S_IFLNK only, a translator like firmlink could easily spoof this check by not showing S_IFLNK, but in fact redirecting the lookup to some other name (i.e. opening the very same holes a symlink would). @@ -145,23 +145,27 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port) one exception to our general translator-based rule. */ struct stat64 st; err = __io_stat (*result, &st); - if (!err - && (st.st_mode & (S_IPTRANS|S_IATRANS))) + if (!err) { - if (st.st_uid != 0) - err = ENOENT; - else if (st.st_mode & S_IPTRANS) + if (S_ISLNK (st.st_mode)) + err = ELOOP; + else if (st.st_mode & (S_IPTRANS|S_IATRANS)) { - char buf[1024]; - char *trans = buf; - size_t translen = sizeof buf; - err = __file_get_translator (*result, - &trans, &translen); - if (!err - && translen > sizeof _HURD_SYMLINK - && !memcmp (trans, - _HURD_SYMLINK, sizeof _HURD_SYMLINK)) - err = ENOENT; + if (st.st_uid != 0) + err = ELOOP; + else if (st.st_mode & S_IPTRANS) + { + char buf[1024]; + char *trans = buf; + size_t translen = sizeof buf; + err = __file_get_translator (*result, + &trans, &translen); + if (!err + && translen > sizeof _HURD_SYMLINK + && !memcmp (trans, + _HURD_SYMLINK, sizeof _HURD_SYMLINK)) + err = ELOOP; + } } } }