Races in affs_unlink(), affs_rmdir() and affs_rename()

From: Alexander Viro (viro@math.psu.edu)
Date: Sat Apr 21 2001 - 16:06:37 EDT

  • Next message: Jochen Striepe: "2.4.4-pre6 does not compile"

    mkdir /A
    mkdir /B
    mkdir /C
    touch /A/a
    ln /A/a /B/b
    ln /A/a /C/c
    rm /A/a &
    rm /B/b

    can corrupt filesystem. Scenario:

    unlink("/B/b") locks /B, removes "b" and unlocks /B. Then it calls
    affs_remove_link(), which blocks.

    unlink("/A/a") locks /A, removes "a" and unlocks /A. Then it calls
    affs_remove_link(). Which locks /B, renames removed entry into "b",
    removes old "b" and inserts renamed "a" into /B.

    The rest is irrelevant - we're already in it.

    Similar race exists between unlink() and rename();

    mkdir /A
    mkdir /B
    mkdir /C
    touch /A/a
    touch /B/a
    ln /A/a /B/b
    ln /A/a /C/c
    rm /A/a &
    mv /B/a /B/b
    - similar scenario, different source of affs_remove_header().

    Another one: unlink() and rmdir():
    mkdir /A
    mkdir /B
    touch /A/a
    ln /A/a /B/a
    rm /A/a &
    rmdir /B

    Since you don't lock /B for affs_empty_dir(), you can hit the
    window between removing old /B/a and inserting renamed /A/a into /B.
    Notice that VFS _does_ lock /B (->i_zombie), but affs_remove_link()
    for /A/a doesn't even look at it.

    Same thing for rename()/rmdir() (rmdir victim contains a link to rename
    target, apply the previous scenario).
                                                                    Al

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/



    This archive was generated by hypermail 2b29 : Sat Apr 21 2001 - 16:09:54 EDT