Skip to contentSkip to conversation

Patch "mnt: Protect the mountpoint hashtable with mount_lock" has been added to the 4.9-stable tree

PATCH [email protected] 1 participant 1 message Jan 17, 2017

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

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 3895dbf8985f656675b5bde610723a29cbce3fa7 Mon 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_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 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.

Fixes ce07d891a089 ("mnt: Honor MNT_LOCKED when detaching mounts")
---
 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