From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS22989 209.51.188.0/24 X-Spam-Status: No, score=-4.0 required=3.0 tests=AWL,BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, RCVD_IN_DNSWL_LOW,SPF_HELO_NONE,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id 4F7B91F45E for ; Sun, 16 Feb 2020 22:29:08 +0000 (UTC) Received: from localhost ([::1]:37526 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j3SPT-0004CQ-IG for normalperson@yhbt.net; Sun, 16 Feb 2020 17:29:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:52675) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j3SPP-0004CK-6O for bug-gnulib@gnu.org; Sun, 16 Feb 2020 17:29:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j3SPN-0000B2-5r for bug-gnulib@gnu.org; Sun, 16 Feb 2020 17:29:03 -0500 Received: from mo6-p01-ob.smtp.rzone.de ([2a01:238:20a:202:5301::7]:16962) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j3SPM-00007x-KH for bug-gnulib@gnu.org; Sun, 16 Feb 2020 17:29:01 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1581892138; s=strato-dkim-0002; d=clisp.org; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=AfXENIleIgSQ4NQ8ucBsRoV57vkRAn10R/3+3DJU0Cg=; b=ka3pRKJZSvxyWF+Q1x8IiMnCvEpSSDdo7ued8zIh8eC/aTgPTkwR+wupE6IqMcKbVU VhHNBQRkL8dRICKungP2SxBKCELV/4YDZuaVQu9uSnS3exR68Wh4hwRaZyXXTwnjjVJ/ ji4HXLQwuHv4RJCzNz5N2mEZtd9BOGnR9NX8q+4Kk1xJWkkslWBAM+TLctmQ0BBYQ1lQ WWm3cLOm4He2thZLsEHDsflaKnSh71byqVRTLOjmDfBi6GT8tfe+rMYEX94g2sfU1ibY 56gcpCNgaU9fkTST8OjX5ehde8b8kYbJr0aO8koyPXvi1OQVf+O10ZHJHhntnhQwgwHf AH6w== X-RZG-AUTH: ":Ln4Re0+Ic/6oZXR1YgKryK8brlshOcZlIWs+iCP5vnk6shH+AHjwLuWOH6fzxfs=" X-RZG-CLASS-ID: mo00 Received: from bruno.haible.de by smtp.strato.de (RZmta 46.1.12 DYNA|AUTH) with ESMTPSA id g00701w1GMSwDd1 (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (curve X9_62_prime256v1 with 256 ECDH bits, eq. 3072 bits RSA)) (Client did not present a certificate); Sun, 16 Feb 2020 23:28:58 +0100 (CET) From: Bruno Haible To: Paul Eggert Subject: Re: [PATCH] fchmodat, lchmod: port to buggy Linux filesystems Date: Sun, 16 Feb 2020 23:28:57 +0100 Message-ID: <7465802.0IcT30DC8I@omega> User-Agent: KMail/5.1.3 (Linux/4.4.0-171-generic; KDE/5.18.0; x86_64; ; ) In-Reply-To: <3279179.fFYm18bb12@omega> References: <20200213184209.34020-1-eggert@cs.ucla.edu> <3279179.fFYm18bb12@omega> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="nextPart2833907.8LCG1p12I0" Content-Transfer-Encoding: 7Bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a01:238:20a:202:5301::7 X-BeenThere: bug-gnulib@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Gnulib discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: bug-gnulib@gnu.org Errors-To: bug-gnulib-bounces+normalperson=yhbt.net@gnu.org Sender: "bug-gnulib" This is a multi-part message in MIME format. --nextPart2833907.8LCG1p12I0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" > > Perhaps lchmod.m4 and fchmodat.m4 should define a symbol > > HAVE_LCHMOD_BUG_WITH_NON_SYMLINKS and the C code could refer to that. > 2020-02-16 Bruno Haible > > lchmod: Make more future-proof. > * m4/lchmod.m4 (gl_FUNC_LCHMOD): Define NEED_LCHMOD_NONSYMLINK_FIX. > (gl_PREREQ_LCHMOD): New macro. > * lib/lchmod.c (orig_lchmod): New function. > (lchmod): Test NEED_LCHMOD_NONSYMLINK_FIX. Access /proc only on Linux. > Return EOPNOTSUPP only on Linux and on platforms without lchmod > function. > * modules/lchmod (configure.ac): Invoke gl_PREREQ_LCHMOD. And here's a similar change for 'fchmodat'. It has one or two code branches that currently are dead code, but this is on purpose: this is code that will becomes active when either the NEED_FCHMODAT_NONSYMLINK_FIX test will trigger on more platforms, or some more autoconf tests will be added to fchmodat.m4. 2020-02-16 Bruno Haible fchmodat: Make more future-proof. * m4/fchmodat.m4 (gl_FUNC_FCHMODAT): Define NEED_FCHMODAT_NONSYMLINK_FIX. (gl_PREREQ_FCHMODAT): New macro. * lib/fchmodat.c (fchmodat): Test NEED_FCHMODAT_NONSYMLINK_FIX. Access /proc only on Linux. Return EOPNOTSUPP only on Linux and on platforms without lchmod function. * modules/fchmodat (configure.ac): Invoke gl_PREREQ_FCHMODAT. --nextPart2833907.8LCG1p12I0 Content-Disposition: attachment; filename="0001-fchmodat-Make-more-future-proof.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="UTF-8"; name="0001-fchmodat-Make-more-future-proof.patch" >From f4693b0166bab83ab232dcd3cfd95906411d1110 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 16 Feb 2020 23:01:08 +0100 Subject: [PATCH] fchmodat: Make more future-proof. * m4/fchmodat.m4 (gl_FUNC_FCHMODAT): Define NEED_FCHMODAT_NONSYMLINK_FIX. (gl_PREREQ_FCHMODAT): New macro. * lib/fchmodat.c (fchmodat): Test NEED_FCHMODAT_NONSYMLINK_FIX. Access /proc only on Linux. Return EOPNOTSUPP only on Linux and on platforms without lchmod function. * modules/fchmodat (configure.ac): Invoke gl_PREREQ_FCHMODAT. --- ChangeLog | 11 +++++++++++ lib/fchmodat.c | 30 +++++++++++++++++++++++------- m4/fchmodat.m4 | 15 +++++++++++++-- modules/fchmodat | 1 + 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 30cc425..8215147 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ 2020-02-16 Bruno Haible + fchmodat: Make more future-proof. + * m4/fchmodat.m4 (gl_FUNC_FCHMODAT): Define + NEED_FCHMODAT_NONSYMLINK_FIX. + (gl_PREREQ_FCHMODAT): New macro. + * lib/fchmodat.c (fchmodat): Test NEED_FCHMODAT_NONSYMLINK_FIX. Access + /proc only on Linux. Return EOPNOTSUPP only on Linux and on platforms + without lchmod function. + * modules/fchmodat (configure.ac): Invoke gl_PREREQ_FCHMODAT. + +2020-02-16 Bruno Haible + lchmod: Make more future-proof. * m4/lchmod.m4 (gl_FUNC_LCHMOD): Define NEED_LCHMOD_NONSYMLINK_FIX. (gl_PREREQ_LCHMOD): New macro. diff --git a/lib/fchmodat.c b/lib/fchmodat.c index 02e2da9..bb48b44 100644 --- a/lib/fchmodat.c +++ b/lib/fchmodat.c @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -/* written by Jim Meyering */ +/* written by Jim Meyering and Paul Eggert */ /* If the user's config.h happens to include , let it include only the system's here, so that orig_fchmodat doesn't recurse to @@ -63,16 +63,27 @@ orig_fchmodat (int dir, char const *file, mode_t mode, int flags) int fchmodat (int dir, char const *file, mode_t mode, int flags) { +# if NEED_FCHMODAT_NONSYMLINK_FIX if (flags == AT_SYMLINK_NOFOLLOW) { struct stat st; -# if defined O_PATH && defined AT_EMPTY_PATH +# if defined O_PATH && defined AT_EMPTY_PATH \ + && (defined __linux__ || defined __ANDROID__) + /* Open a file descriptor with O_NOFOLLOW, to make sure we don't + follow symbolic links, if /proc is mounted. O_PATH is used to + avoid a failure if the file is not readable. + Cf. */ int fd = openat (dir, file, O_PATH | O_NOFOLLOW | O_CLOEXEC); if (fd < 0) return fd; - /* Use fstatat because fstat does not work on O_PATH descriptors + /* Up to Linux 5.3 at least, when FILE refers to a symbolic link, the + chmod call below will change the permissions of the symbolic link + - which is undersired - and on many file systems (ext4, btrfs, jfs, + xfs, ..., but not reiserfs) fail with error EOPNOTSUPP - which is + misleading. Therefore test for a symbolic link explicitly. + Use fstatat because fstat does not work on O_PATH descriptors before Linux 3.6. */ if (fstatat (fd, "", &st, AT_EMPTY_PATH) != 0) { @@ -102,7 +113,9 @@ fchmodat (int dir, char const *file, mode_t mode, int flags) return chmod_result; } /* /proc is not mounted. */ -# else + /* Fall back on orig_fchmodat, despite the race. */ + return orig_fchmodat (dir, file, mode, 0); +# elif (defined __linux__ || defined __ANDROID__) || !HAVE_LCHMOD int fstatat_result = fstatat (dir, file, &st, AT_SYMLINK_NOFOLLOW); if (fstatat_result != 0) return fstatat_result; @@ -111,10 +124,13 @@ fchmodat (int dir, char const *file, mode_t mode, int flags) errno = EOPNOTSUPP; return -1; } -# endif - /* Fall back on chmod, despite the race. */ - flags = 0; + /* Fall back on orig_fchmodat, despite the race. */ + return orig_fchmodat (dir, file, mode, 0); +# else + return orig_fchmodat (dir, file, mode, 0); +# endif } +# endif return orig_fchmodat (dir, file, mode, flags); } diff --git a/m4/fchmodat.m4 b/m4/fchmodat.m4 index f284485..e3f2f04 100644 --- a/m4/fchmodat.m4 +++ b/m4/fchmodat.m4 @@ -1,4 +1,4 @@ -# fchmodat.m4 serial 3 +# fchmodat.m4 serial 4 dnl Copyright (C) 2004-2020 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -65,7 +65,18 @@ AC_DEFUN([gl_FUNC_FCHMODAT], rm -f conftest.fchmodat]) case $gl_cv_func_fchmodat_works in *yes) ;; - *) REPLACE_FCHMODAT=1;; + *) + AC_DEFINE([NEED_FCHMODAT_NONSYMLINK_FIX], [1], + [Define to 1 if fchmodat+AT_SYMLINK_NOFOLLOW does not work right on non-symlinks.]) + REPLACE_FCHMODAT=1 + ;; esac fi ]) + +# Prerequisites of lib/fchmodat.c. +AC_DEFUN([gl_PREREQ_FCHMODAT], +[ + AC_CHECK_FUNCS_ONCE([lchmod]) + : +]) diff --git a/modules/fchmodat b/modules/fchmodat index b0f06e8..f0dac9d 100644 --- a/modules/fchmodat +++ b/modules/fchmodat @@ -28,6 +28,7 @@ configure.ac: gl_FUNC_FCHMODAT if test $HAVE_FCHMODAT = 0 || test $REPLACE_FCHMODAT = 1; then AC_LIBOBJ([fchmodat]) + gl_PREREQ_FCHMODAT fi gl_MODULE_INDICATOR([fchmodat]) dnl for lib/openat.h gl_SYS_STAT_MODULE_INDICATOR([fchmodat]) -- 2.7.4 --nextPart2833907.8LCG1p12I0--