From 04bd5d65d0e56890213ee0871b48f8b07fb7ad97 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 18 Dec 2014 10:57:19 -0600 Subject: [PATCH] mnt: Fix a memory stomp in umount While reviewing the code of umount_tree I realized that when we append to a preexisting unmounted list we do not change pprev of the former first item in the list. Which means later in namespace_unlock hlist_del_init(&mnt->mnt_hash) on the former first item of the list will stomp unmounted.first leaving it set to some random mount point which we are likely to free soon. This isn't likely to hit, but if it does I don't know how anyone could track it down. [ This happened because we don't have all the same operations for hlist's as we do for normal doubly-linked lists. In particular, list_splice() is easy on our standard doubly-linked lists, while hlist_splice() doesn't exist and needs both start/end entries of the hlist. And commit c70f4b6315db incorrectly open-coded that missing hlist_splice(). We should think about making these kinds of "mindless" conversions easier to get right by adding the missing hlist helpers - Linus ] Fixes: c70f4b6315db0f3c78d453fb561dd3078f9f57b1 switch mnt_hash to hlist Cc: stable@vger.kernel.org Signed-off-by: "Eric W. Biederman" Signed-off-by: Linus Torvalds --- fs/namespace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/namespace.c b/fs/namespace.c index 820af6a1dd6b1..cd1e9681a0cf5 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1370,6 +1370,8 @@ void umount_tree(struct mount *mnt, int how) } if (last) { last->mnt_hash.next = unmounted.first; + if (unmounted.first) + unmounted.first->pprev = &last->mnt_hash.next; unmounted.first = tmp_list.first; unmounted.first->pprev = &unmounted.first; } -- 2.39.5