Note: This is a beta release of Red Hat Bugzilla 5.0. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Also email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback here.

Bug 84552

Summary: rm fails in fileutils 4.0x-3.1 when it can't lstat the current directory
Product: Red Hat Enterprise Linux 2.1 Reporter: Terry Griffin <griffint>
Component: fileutilsAssignee: Tim Waugh <twaugh>
Status: CLOSED ERRATA QA Contact: Mike McLean <mikem>
Severity: medium Docs Contact:
Priority: medium    
Version: 2.1CC: greg.marsden, kin.au, robinson, tao
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2004-08-18 15:52:33 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Attachments:
Description Flags
patch to fix rm behavior.
none
rmfix patch, take 2 none

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):

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 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
question?

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:
#!/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-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.

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 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
directory.

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.

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