• Eric W. Biederman's avatar
    mnt: Protect the mountpoint hashtable with mount_lock · 3895dbf8
    Eric W. Biederman authored
    Protecting the mountpoint hashtable with namespace_sem was sufficient
    until a call to umount_mnt was added to mntput_no_expire.  At which
    point it became possible for multiple calls of put_mountpoint on
    the same hash chain to happen on the same time.
    Kristen Johansen <kjlx@templeofstupid.com> reported:
    > This can cause a panic when simultaneous callers of put_mountpoint
    > attempt to free the same mountpoint.  This occurs because some callers
    > hold the mount_hash_lock, while others hold the namespace lock.  Some
    > even hold both.
    > In this submitter's case, the panic manifested itself as a GP fault in
    > put_mountpoint() when it called hlist_del() and attempted to dereference
    > a m_hash.pprev that had been poisioned by another thread.
    Al Viro observed that the simple fix is to switch from using the namespace_sem
    to the mount_lock to protect the mountpoint hash table.
    I have taken Al's suggested patch moved put_mountpoint in pivot_root
    (instead of taking mount_lock an additional time), and have replaced
    new_mountpoint with get_mountpoint a function that does the hash table
    lookup and addition under the mount_lock.   The introduction of get_mounptoint
    ensures that only the mount_lock is needed to manipulate the mountpoint
    d_set_mounted is modified to only set DCACHE_MOUNTED if it is not
    already set.  This allows get_mountpoint to use the setting of
    DCACHE_MOUNTED to ensure adding a struct mountpoint for a dentry
    happens exactly once.
    Cc: stable@vger.kernel.org
    Fixes: ce07d891 ("mnt: Honor MNT_LOCKED when detaching mounts")
    Reported-by: default avatarKrister Johansen <kjlx@templeofstupid.com>
    Suggested-by: default avatarAl Viro <viro@ZenIV.linux.org.uk>
    Acked-by: default avatarAl Viro <viro@ZenIV.linux.org.uk>
    Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
dcache.c 93.8 KB