GNU bug report logs - #9813
rm -rf calls rmdir() prior to close(), which can fail

Previous Next

Package: coreutils;

Reported by: Eric Blake <eblake <at> redhat.com>

Date: Thu, 20 Oct 2011 17:41:01 UTC

Severity: normal

Done: Jim Meyering <jim <at> meyering.net>

Bug is archived. No further changes may be made.

Full log


Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Eric Blake <eblake <at> redhat.com>
To: bug-coreutils <bug-coreutils <at> gnu.org>, bug-gnulib <bug-gnulib <at> gnu.org>
Subject: rm -rf calls rmdir() prior to close(), which can fail
Date: Thu, 20 Oct 2011 11:38:36 -0600
POSIX is clear that attempts to rmdir() a directory that still has open 
descriptors may fail.  Of course, on Linux, this (rather limiting) 
restriction is not present, so we don't notice it; but on Cygwin, there 
are certain file systems where this is a real problem, such as in this 
thread:
http://cygwin.com/ml/cygwin/2011-10/msg00365.html

Looking at an strace on Linux reveals the problem (abbreviated to show 
highlights here):

$ mkdir -p a/b
$ strace rm -f a
...
openat(AT_FDCWD, "a", 
O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = 3
...
fcntl(3, F_DUPFD, 3)                    = 4
...
close(3)                                = 0
...
openat(4, "b", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = 3
...
fcntl(3, F_DUPFD, 3)                    = 5
...
close(3)                                = 0
close(5)                                = 0
unlinkat(4, "b", AT_REMOVEDIR)          = 0
unlinkat(AT_FDCWD, "a", AT_REMOVEDIR)   = 0
close(4)                                = 0

Notice that for subdirectories, we opened the directory, then used dup 
to have a handle for use in further *at calls, then do 
fdopendir/readdir/closedir on the DIR*, then close the duplicate fd, all 
before calling unlinkat (aka rmdir) on that subdirectory.  But for the 
top-level directory, the dup'd fd (4) is still open when we attempt the 
unlinkat.

I'm still trying to investigate whether the fix needs to be in gnulib or 
just coreutils, but something needs to be done to swap the order so that 
the last handle to the directory is closed prior to the rmdir attempt.

-- 
Eric Blake   eblake <at> redhat.com    +1-801-349-2682
Libvirt virtualization library http://libvirt.org




This bug report was last modified 13 years and 298 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.