Subject: bug#11108: closed (Re: bug#11108: [PATCH] chmod: fix symlink race condition)

From: [email-masked] (GNU bug Tracking System)
Date: Wed, 20 Mar 2024 19:10:02 +0000

Your bug report

#11108: chmod: fix symlink race condition

which was filed against the coreutils package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
11108: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=11108
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#11108: [PATCH] chmod: fix symlink race condition
From: Pádraig Brady <[email-masked]>
To: [email-masked]
Date: Wed, 20 Mar 2024 19:01:22 +0000
List-Id: <debbugs-submit.debbugs.gnu.org>

On 28/03/2012 21:28, Paul Eggert wrote:
> On 03/28/2012 01:13 PM, Jim Meyering wrote:
>>      $ ./chmod u+w f
>>      ./chmod: changing permissions of 'f': Operation not supported
> 
> Yeouch.  I undid the change for now.
> Hmm, why did "make check" work for me?
> I'll have to investigate later, alas.

Patch for this pushed at:
https://git.sv.gnu.org/cgit/coreutils.git/commit/?id=v9.4-163-g425b8a2f5

Marking this as done.

cheers,
Pádraig.

Subject: [PATCH] chmod: fix symlink race condition
From: Paul Eggert <[email-masked]>
To: [email-masked]
Date: Tue, 27 Mar 2012 22:28:31 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

This fixes what I hope is an obvious race condition
that can occur if some other process substitutes a
symlink for a non-symlink while chmod is running.

=====
* src/chmod.c (process_file): Don't follow symlink if we
think the file is not a symlink.
---
 src/chmod.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/src/chmod.c b/src/chmod.c
index aa4ac77..2e1f1c7 100644
--- a/src/chmod.c
+++ b/src/chmod.c
@@ -268,7 +268,15 @@ process_file (FTS *fts, FTSENT *ent)
 
       if (! S_ISLNK (old_mode))
         {
-          if (chmodat (fts->fts_cwd_fd, file, new_mode) == 0)
+          /* Use any native support for AT_SYMLINK_NOFOLLOW, to avoid
+             following a symlink if there is a race.  */
+          #if HAVE_FCHMODAT || HAVE_LCHMOD
+          int follow_flag = AT_SYMLINK_NOFOLLOW;
+          #else
+          int follow_flag = 0;
+          #endif
+
+          if (fchmodat (fts->fts_cwd_fd, file, new_mode, follow_flag) == 0)
             chmod_succeeded = true;
           else
             {
-- 
1.7.6.5