Bug 84552 - rm fails in fileutils 4.0x-3.1 when it can't lstat the current directory
Summary: rm fails in fileutils 4.0x-3.1 when it can't lstat the current directory
Alias: None
Product: Red Hat Enterprise Linux 2.1
Classification: Red Hat
Component: fileutils
Version: 2.1
Hardware: i386
OS: Linux
Target Milestone: ---
Assignee: Tim Waugh
QA Contact: Mike McLean
: 123071 (view as bug list)
Depends On:
Blocks: 116726
TreeView+ depends on / blocked
Reported: 2003-02-18 18:52 UTC by Terry Griffin
Modified: 2007-11-30 22:06 UTC (History)
4 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Last Closed: 2004-08-18 15:52:33 UTC
Target Upstream Version:

Attachments (Terms of Use)
patch to fix rm behavior. (1.47 KB, patch)
2004-05-17 19:23 UTC, Greg Marsden
no flags Details | Diff
rmfix patch, take 2 (1.86 KB, patch)
2004-05-19 17:06 UTC, Greg Marsden
no flags Details | Diff

System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2004:230 0 normal SHIPPED_LIVE Updated fileutils package fixes two bugs 2004-08-18 04:00:00 UTC

Description Terry Griffin 2003-02-18 18:52:18 UTC
Description of problem:

If the 'rm' command is executed while the current working directory is
not searchable (+x permission) by the effective user, then rm will fail
on a call to lstat() of the current directroy and the files specified
on the command line will not be removed, even if the current user has
the right to delete those files.

Version-Release number of selected component (if applicable):


How reproducible:


Steps to Reproduce:

1. Create a directory.
2. CD in to that directory.
3. After CD'ing, remove search permissions from that directory (chmod -x).
4. Then while in that directory try to 'rm' a file. You'll get this error:

   rm: cannot lstat `.': Permission denied

and the file will not be removed.    
Actual results:

Files not removed.

Expected results:

Files removed.

Additional info:

Comment 1 Tim Waugh 2003-02-18 19:09:35 UTC
Nothing fileutils can do about it; that's just how permissions work on
directories I think.

$ strace -feunlink perl -e 'unlink ("file")'
unlink("file")                          = -1 EACCES (Permission denied)

Comment 2 Terry Griffin 2003-02-18 19:31:48 UTC
Well the previous version of fileutils didn't have this problem. So me 
thinks that it is not unavoidable. 

Comment 3 Tim Waugh 2003-02-18 20:41:56 UTC
Which version, specifically?

Comment 4 Terry Griffin 2003-02-18 21:42:24 UTC
As there appears to be no older fileutils RPMs on my Red Hat update mirror,  
the previous version must have been the one from the Red Hat 7.0 CD-ROM  
which is fileutils-4.0x-3.  
The reason I know the previous version worked is that I had a /etc/procmailrc 
invoked spam-checking script that broke when fileutils was upgraded last 
Thursday. The script was doing an "rm -f" on a lock file created by procmail's  
'lockfile' utility. In some instances the script's PWD happened to be one that was 
not searchable. But since the script never actually does anything in PWD this 
never mattered before the upgrade. I could imagine lots of system scripts breaking 
in this fashion, where before now they never cared about the current PWD 
because they didn't use it for anything. Now "rm" creates an unnecessary 
dependency on PWD's permissions. 

Comment 5 Tim Waugh 2003-02-18 21:52:47 UTC
Do you mean that the file that you're trying to remove isn't in the directory in

Please supply a real test case that I can try.

Comment 6 Terry Griffin 2003-02-18 22:28:44 UTC
Yes, the file I'm trying to delete is *not* in the current directory. It's elsewhere 
on the file system. The procedure is described in the original bug report. But I 
now see that step #4 is not clear. It should be: 
4. Then while in that directory, 'rm' a file that resides elsewhere on the 
file system. You'll get this error: 
   rm: cannot lstat `.': Permission denied 
and the file will not be removed.     
Sorry about that. The things a little lack of clarity will lead to. 

Comment 7 Mike McLean 2003-02-19 00:38:56 UTC
I am unable to replicate this with the version mentioned: fileutils-4.0x-3.1

I used the following script:
file=$(mktemp /tmp/file.XXXXXX)
dir=$(mktemp -d /tmp/dir.XXXXXX)
relpath="../$(basename $file)"
echo "Using file $file and directory $dir"
ls -ld $dir
ls -l $file
cd $dir
touch $(seq 10)
echo Changing permissions on $dir
chmod a-rwx $dir
ls -ld $dir
echo "Removing $relpath (cwd is $PWD)"
rm $relpath && ! [ -e $file ] || echo rm failed
echo "Cleaning up"
chmod u+rwx $dir
rm -rf $dir

Comment 8 Terry Griffin 2003-02-19 01:19:25 UTC
Running your script on my system gives this output: 
Using file /tmp/file.qPHPcS and directory /tmp/dir.Jt050R 
drwx------    2 terryg   terryg       4096 Feb 18 17:13 /tmp/dir.Jt050R 
-rw-------    1 terryg   terryg          0 Feb 18 17:13 /tmp/file.qPHPcS 
Changing permissions on /tmp/dir.Jt050R 
d---------    2 terryg   terryg       4096 Feb 18 17:13 /tmp/dir.Jt050R 
Removing ../file.qPHPcS (cwd is /tmp/dir.Jt050R) 
rm: cannot lstat `.': Permission denied 
rm failed 
Cleaning up 

Comment 9 Tim Waugh 2003-03-03 16:11:28 UTC
I get the same result as Mike.

Comment 10 Terry Griffin 2003-03-04 03:25:50 UTC
Did you run the script as root or as a regular user? For me the
script works fine as root but fails as a regular user.

Comment 11 Tim Waugh 2003-03-04 10:45:26 UTC
Okay, I see it now.

Comment 12 Tim Waugh 2004-05-12 08:28:23 UTC
*** Bug 123071 has been marked as a duplicate of this bug. ***

Comment 13 Greg Marsden 2004-05-13 16:00:20 UTC
If the current directory does not exist, rm fails
immediately.  This is a result of a bad security
fix for fileutils 4.1 and is fixed in 4.5 and later.

The problem is only on AS2.1

A trivial testcase to reproduce this problem is:
[0] gmarsden@ca-build1:/tmp$ mkdir rmtest
[0] gmarsden@ca-build1:/tmp$ cd rmtest/
[0] gmarsden@ca-build1:/tmp/rmtest$ touch /tmp/file1
[0] gmarsden@ca-build1:/tmp/rmtest$ chmod 0 .
[0] gmarsden@ca-build1:/tmp/rmtest$ rm -f /tmp/file1
rm: cannot lstat `.': Permission denied
[1] gmarsden@ca-build1:/tmp/rmtest$ ls -l /tmp/file1
-rw-rw-r--    1 gmarsden gmarsden        0 May  7 18:52 /tmp/file1

The offending code is actually flagged with a FIXME in the
AS2.1 fileutils package and results from attempting to do an lstat on
the current directory to prevent a security exploit. However, this
check should not happen when not removing recursive directories.

Comment 14 Greg Marsden 2004-05-17 19:23:10 UTC
Created attachment 100278 [details]
patch to fix rm behavior.

Patch to fix rm for file-delete

Comment 16 Tim Waugh 2004-05-19 16:04:49 UTC
The rm.c part looks like it is reversed to me.


if (lstat (...))

carry on;


if (lstat (...))
  carry on;

Shouldn't the if/else clauses be the other way around?

In the first hunk from remove.c, 'sb' is initialised from a checked
lstat() called after a successful chdir(), so there's no reason I can
see that sb->st_dev or sb->st_ino would be NULL.  Did you mean

Similarly for hunk #2 from remove.c: why would sb have NULL
st_dev/st_ino here?

Comment 17 Greg Marsden 2004-05-19 17:06:28 UTC
Created attachment 100350 [details]
rmfix patch, take 2

Ok, that was silly, thanks for noticing the reversed call path. Here's a new,
cleaner, patch.

The only parameter which must be checked for null is cwd_dev_ino,which is
passed from the 
initial lstat into the remove_dir function, and could be set to null by the new
code in rm.c. As you noticed, only one null check is required in remove.c

There's no need to check *fs, as that lstat is being done from the present

Comment 18 Tim Waugh 2004-05-20 11:00:16 UTC
Yes, this patch looks good -- thanks.

Comment 23 John Flanagan 2004-08-18 15:52:33 UTC
An errata has been issued which should help the problem 
described in this bug report. This report is therefore being 
closed with a resolution of ERRATA. For more information
on the solution and/or where to find the updated files, 
please follow the link below. You may reopen this bug report 
if the solution does not work for you.


Note You need to log in before you can comment on or make changes to this bug.