lkml.org 
[lkml]   [2007]   [Apr]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[AppArmor 32/41] Make d_path() consistent across mount operations
    Right now, the path that __d_path() computes can become slightly
    inconsistent when it races with mount operations: it grabs the
    vfsmount_lock when traversing mount points, but immediately drops it
    again, only to re-grab it when it reaches the next mount point.
    The result is that the filename computed is not always consisent, and
    the file may never have had that name. (This is unlikely, but still
    possible.)

    We can easily fix this by grabbing the vfsmount_lock when the first
    mount point is reached, and holding onto it until the d_cache lookup is
    completed.

    Signed-off-by: Andreas Gruenbacher <agruen@suse.de>

    ---
    fs/dcache.c | 14 ++++++++------
    1 file changed, 8 insertions(+), 6 deletions(-)

    --- a/fs/dcache.c
    +++ b/fs/dcache.c
    @@ -1754,7 +1754,7 @@ static char *__d_path(struct dentry *den
    struct dentry *root, struct vfsmount *rootmnt,
    char *buffer, int buflen, int fail_deleted)
    {
    - int namelen, is_slash;
    + int namelen, is_slash, vfsmount_locked = 0;

    if (buflen < 2)
    return ERR_PTR(-ENAMETOOLONG);
    @@ -1777,14 +1777,14 @@ static char *__d_path(struct dentry *den
    struct dentry * parent;

    if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
    - spin_lock(&vfsmount_lock);
    - if (vfsmnt->mnt_parent == vfsmnt) {
    - spin_unlock(&vfsmount_lock);
    - goto global_root;
    + if (!vfsmount_locked) {
    + spin_lock(&vfsmount_lock);
    + vfsmount_locked = 1;
    }
    + if (vfsmnt->mnt_parent == vfsmnt)
    + goto global_root;
    dentry = vfsmnt->mnt_mountpoint;
    vfsmnt = vfsmnt->mnt_parent;
    - spin_unlock(&vfsmount_lock);
    continue;
    }
    parent = dentry->d_parent;
    @@ -1803,6 +1803,8 @@ static char *__d_path(struct dentry *den
    *--buffer = '/';

    out:
    + if (vfsmount_locked)
    + spin_unlock(&vfsmount_lock);
    spin_unlock(&dcache_lock);
    return buffer;

    --
    -
    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/

    \
     
     \ /
      Last update: 2007-04-12 11:47    [W:4.309 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site