[PATCH] Fix mm->owner point to a task that does not exists.

From: gchen . guomin
Date: Tue Dec 11 2018 - 20:54:29 EST


From: guomin chen <gchen.guomin@xxxxxxxxx>

Under normal circumstances,When do_exit exits, mm->owner will
be updated on exit_mm(). but when the kernel process calls
unuse_mm() and then exits,mm->owner cannot be updated. And it
will point to a task that has been released.

Below is my issue on vhost_net:
A, B are two kernel processes(such as vhost_worker),
C is a user space process(such as qemu), and all
three use the mm of the user process C.
Now, because user process C exits abnormally, the owner of this
mm becomes A. When A calls unuse_mm and exits, this mm->ower
still points to the A that has been released.
When B accesses this mm->owner again, A has been released.

Process A Process B
vhost_worker() vhost_worker()
--------- ---------
use_mm() use_mm()
...
unuse_mm()
tsk->mm=NULL
do_exit() page fault
exit_mm() access mm->owner
can't update owner kernel Oops

unuse_mm()

Cc: "Michael S. Tsirkin" <mst@xxxxxxxxxx>
Cc: Jason Wang <jasowang@xxxxxxxxxx>
Cc: <kvm@xxxxxxxxxxxxxxx>
Cc: <virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx>
Cc: <netdev@xxxxxxxxxxxxxxx>
Cc: <linux-kernel@xxxxxxxxxxxxxxx>
Signed-off-by: guomin chen <gchen.guomin@xxxxxxxxx>
---
drivers/vhost/vhost.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 6b98d8e..7f8586a 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -368,6 +368,10 @@ static int vhost_worker(void *data)
}
}
unuse_mm(dev->mm);
+ /* current->mm needs to be processed by the later exit_mm() */
+ task_lock(current);
+ current->mm = dev->mm;
+ task_unlock(current);
set_fs(oldfs);
return 0;
}
--
1.8.3.1