bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

PATCH: rm -rf and readdir bug in coreutils-6.7


From: Mikulas Patocka
Subject: PATCH: rm -rf and readdir bug in coreutils-6.7
Date: Tue, 19 Dec 2006 17:58:24 +0100 (CET)

Hi

I have a system that precaches directory content at opendir call and I found that coreutils-6.7 rm -r command doesn't work on it (it used to work fine in coreutils 5).

The problem is this: when walking up to the root in directory tree, rm opens parent directory with opendir, then deletes its subdirectory with rmdir and then starts reading the parent with readdir --- readdir reads just deleted entry, rm tries to delete it again and fails.

opendir caching is allowed by standard http://www.opengroup.org/onlinepubs/007908799/xsh/readdir.html ("If a file is removed from or added to the directory after the most recent call to opendir() or rewinddir(), whether a subsequent call to readdir() returns an entry for that file is unspecified."), so the system behaves correctly and rm has a bug.

Here is a trace when I tried rm -rf /A and there was four directories /A/B/C/D --- it correctly deletes D, but reads entry for 'D' again and fails.

I made a fix --- it modifies AD_pop_and_chdir so that it only returns fd of a directory but doesn't try to do fdopendir and do fdopendir in remove_dir after the subdirectory is deleted - it seems to work but it makes the file even more messy.

Mikulas

The trace of rm -rf /A, I added printfs to opendir, readdir and closedir to see what happens:

opendir '/A' -> BFFEF950
readdir BFFEF950, pos 0: name '.', dt 4
readdir BFFEF950, pos 1: name '..', dt 4
readdir BFFEF950, pos 2: name 'B', dt 4
opendir '/A/B' -> BFFEF9F0
closedir: BFFEF950
readdir BFFEF9F0, pos 0: name '.', dt 4
readdir BFFEF9F0, pos 1: name '..', dt 4
readdir BFFEF9F0, pos 2: name 'C', dt 4
opendir '/A/B/C' -> BFFEF980
closedir: BFFEF9F0
readdir BFFEF980, pos 0: name '.', dt 4
readdir BFFEF980, pos 1: name '..', dt 4
readdir BFFEF980, pos 2: name 'D', dt 4
opendir '/A/B/C/D' -> BFFEF9C0
closedir: BFFEF980
readdir BFFEF9C0, pos 0: name '.', dt 4
readdir BFFEF9C0, pos 1: name '..', dt 4
closedir: BFFEF9C0
        --- note here: it opens the parent directory and then deletes the
        subdirectory --- the subsequent readdir will read just deleted
        entry
opendir '/A/B/C' -> BFFEBE00
removed directory: `A/B/C/D'
readdir BFFEBE00, pos 0: name '.', dt 4
readdir BFFEBE00, pos 1: name '..', dt 4
        --- here: entry 'D' no longer exists, but it is read from cached
        information on opendir
readdir BFFEBE00, pos 2: name 'D', dt 4
closedir: BFFEBE00
opendir '/A/B' -> BFFEBE00
readdir BFFEBE00, pos 0: name '.', dt 4
readdir BFFEBE00, pos 1: name '..', dt 4
readdir BFFEBE00, pos 2: name 'C', dt 4
closedir: BFFEBE00
opendir '/A' -> BFFEBE00
readdir BFFEBE00, pos 0: name '.', dt 4
readdir BFFEBE00, pos 1: name '..', dt 4
readdir BFFEBE00, pos 2: name 'B', dt 4
closedir: BFFEBE00

Attachment: CORE-FIX
Description: fix for coreutils rm


reply via email to

[Prev in Thread] Current Thread [Next in Thread]