Patch "mnt: Protect the mountpoint hashtable with mount_lock" has been added to the 4.9-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
mnt: Protect the mountpoint hashtable with mount_lock
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
mnt-protect-the-mountpoint-hashtable-with-mount_lock.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
3895dbf8985f656675b5bde610723a29cbce3fa7Mon Sep 17 00:00:00 2001
From: "Eric W. Biederman" <[email protected]>
Date: Tue, 3 Jan 2017 14:18:43 +1300
Subject: mnt: Protect the mountpoint hashtable with mount_lock
From: Eric W. Biederman <[email protected]>
commit 3895dbf8985f656675b5bde610723a29cbce3fa7 upstream.
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 <[email protected]> reported:
Quoted 8 lines
This can cause a panic when simultaneous callers of
put_mountpointattempt to free the same mountpoint. This occurs because some callers hold themount_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 calledhlist_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 hashtable.
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.
--- fs/dcache.c | 7 ++++-- fs/namespace.c | 64 ++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 50 insertions(+), 21 deletions(-)
fs/dcache.c +5 -2
@@ -1330,8 +1330,11 @@ int d_set_mounted(struct dentry *dentry) }spin_lock (&dentry->d_lock);if (!d_unlinked (dentry)) { - dentry->d_flags |=DCACHE_MOUNTED ; - ret =0 ; + ret = -EBUSY ; +if (!d_mountpoint (dentry)) { + dentry->d_flags |=DCACHE_MOUNTED ; + ret =0 ; + } }spin_unlock (&dentry->d_lock); out:
fs/namespace.c +45 -19
116 lines not on this page · raw message
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/pid-fix-lockdep-deadlock-warning-due-to-ucount_lock.patch queue-4.9/mnt-protect-the-mountpoint-hashtable-with-mount_lock.patch