Bug 84552 - rm fails in fileutils 4.0x-3.1 when it can't lstat the current directory
rm fails in fileutils 4.0x-3.1 when it can't lstat the current directory
Status: CLOSED ERRATA
Product: Red Hat Enterprise Linux 2.1
Classification: Red Hat
Component: fileutils (Show other bugs)
2.1
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Tim Waugh
Mike McLean
:
: 123071 (view as bug list)
Depends On:
Blocks: 116726
  Show dependency treegraph
 
Reported: 2003-02-18 13:52 EST by Terry Griffin
Modified: 2007-11-30 17:06 EST (History)
4 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2004-08-18 11:52:33 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


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

  None (edit)
Description Terry Griffin 2003-02-18 13:52:18 EST
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):

4.0x-3.1

How reproducible:

Repeatable.

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 14:09:35 EST
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 14:31:48 EST
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 15:41:56 EST
Which version, specifically?
Comment 4 Terry Griffin 2003-02-18 16:42:24 EST
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 16:52:47 EST
Do you mean that the file that you're trying to remove isn't in the directory in
question?

Please supply a real test case that I can try.
Comment 6 Terry Griffin 2003-02-18 17:28:44 EST
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-18 19:38:56 EST
I am unable to replicate this with the version mentioned: fileutils-4.0x-3.1

I used the following script:
#!/bin/bash
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-18 20:19:25 EST
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 11:11:28 EST
I get the same result as Mike.
Comment 10 Terry Griffin 2003-03-03 22:25:50 EST
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 05:45:26 EST
Okay, I see it now.
Comment 12 Tim Waugh 2004-05-12 04:28:23 EDT
*** Bug 123071 has been marked as a duplicate of this bug. ***
Comment 13 Greg Marsden 2004-05-13 12:00:20 EDT
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 15:23:10 EDT
Created attachment 100278 [details]
patch to fix rm behavior.

Patch to fix rm for file-delete
Comment 16 Tim Waugh 2004-05-19 12:04:49 EDT
The rm.c part looks like it is reversed to me.

Before:

==>
if (lstat (...))
  error;

carry on;
<==

After:

==>
if (lstat (...))
  carry on;
else
  error;
<==

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
(*fs)->st_dev/ino?

Similarly for hunk #2 from remove.c: why would sb have NULL
st_dev/st_ino here?
Comment 17 Greg Marsden 2004-05-19 13:06:28 EDT
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
directory.
Comment 18 Tim Waugh 2004-05-20 07:00:16 EDT
Yes, this patch looks good -- thanks.
Comment 23 John Flanagan 2004-08-18 11:52:33 EDT
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.

http://rhn.redhat.com/errata/RHBA-2004-230.html

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