• Miklos Szeredi's avatar
    [PATCH] namespace.c: fix race in mark_mounts_for_expiry() · 1ce88cf4
    Miklos Szeredi authored
    This patch fixes a race found by Ram in mark_mounts_for_expiry() in
    fs/namespace.c.
    
    The bug can only be triggered with simultaneous exiting of a process having
    a private namespace, and expiry of a mount from within that namespace.
    It's practically impossible to trigger, and I haven't even tried.  But
    still, a bug is a bug.
    
    The race happens when put_namespace() is called by another task, while
    mark_mounts_for_expiry() is between atomic_read() and get_namespace().  In
    that case get_namespace() will be called on an already dead namespace with
    unforeseeable results.
    
    The solution was suggested by Al Viro, with his own words:
    
          Instead of screwing with atomic_read() in there, why don't we
          simply do the following:
          	a) atomic_dec_and_lock() in put_namespace()
          	b) __put_namespace() called without dropping lock
          	c) the first thing done by __put_namespace would be
          struct vfsmount *root = namespace->root;
          namespace->root = NULL;
          spin_unlock(...);
          ....
          umount_tree(root);
          ...
          	d) check in mark_... would be simply namespace && namespace->root.
    
          And we are all set; no screwing around with atomic_read(), no magic
          at all.  Dying namespace gets NULL ->root.
          All changes of ->root happen under spinlock.
          If under a spinlock we see non-NULL ->mnt_namespace, it won't be
          freed until we drop the lock (we will set ->mnt_namespace to NULL
          under that lock before we get to freeing namespace).
          If under a spinlock we see non-NULL ->mnt_namespace and
          ->mnt_namespace->root, we can grab a reference to namespace and be
          sure that it won't go away.
    Signed-off-by: default avatarMiklos Szeredi <miklos@szeredi.hu>
    Acked-by: default avatarAl Viro <viro@parcelfarce.linux.theplanet.co.uk>
    Acked-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
    1ce88cf4
namespace.c 34.8 KB