Files
twx-linux/include/linux
Andrea Arcangeli 465ce9a50f coredump: fix race condition between collapse_huge_page() and core dumping
commit 59ea6d06cf upstream.

When fixing the race conditions between the coredump and the mmap_sem
holders outside the context of the process, we focused on
mmget_not_zero()/get_task_mm() callers in 04f5866e41 ("coredump: fix
race condition between mmget_not_zero()/get_task_mm() and core
dumping"), but those aren't the only cases where the mmap_sem can be
taken outside of the context of the process as Michal Hocko noticed
while backporting that commit to older -stable kernels.

If mmgrab() is called in the context of the process, but then the
mm_count reference is transferred outside the context of the process,
that can also be a problem if the mmap_sem has to be taken for writing
through that mm_count reference.

khugepaged registration calls mmgrab() in the context of the process,
but the mmap_sem for writing is taken later in the context of the
khugepaged kernel thread.

collapse_huge_page() after taking the mmap_sem for writing doesn't
modify any vma, so it's not obvious that it could cause a problem to the
coredump, but it happens to modify the pmd in a way that breaks an
invariant that pmd_trans_huge_lock() relies upon.  collapse_huge_page()
needs the mmap_sem for writing just to block concurrent page faults that
call pmd_trans_huge_lock().

Specifically the invariant that "!pmd_trans_huge()" cannot become a
"pmd_trans_huge()" doesn't hold while collapse_huge_page() runs.

The coredump will call __get_user_pages() without mmap_sem for reading,
which eventually can invoke a lockless page fault which will need a
functional pmd_trans_huge_lock().

So collapse_huge_page() needs to use mmget_still_valid() to check it's
not running concurrently with the coredump...  as long as the coredump
can invoke page faults without holding the mmap_sem for reading.

This has "Fixes: khugepaged" to facilitate backporting, but in my view
it's more a bug in the coredump code that will eventually have to be
rewritten to stop invoking page faults without the mmap_sem for reading.
So the long term plan is still to drop all mmget_still_valid().

Link: http://lkml.kernel.org/r/20190607161558.32104-1-aarcange@redhat.com
Fixes: ba76149f47 ("thp: khugepaged")
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Reported-by: Michal Hocko <mhocko@suse.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Jann Horn <jannh@google.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Mike Rapoport <rppt@linux.vnet.ibm.com>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Jason Gunthorpe <jgg@mellanox.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-22 08:15:21 +02:00
..
2019-04-17 08:38:42 +02:00
2018-05-26 09:16:44 +02:00
2019-04-20 09:16:05 +02:00
2011-03-11 14:25:50 +00:00
2018-05-09 17:25:13 +02:00
2018-06-19 10:06:29 -07:00
2018-08-22 10:52:48 -07:00
2019-03-23 20:10:09 +01:00
2018-01-01 12:40:27 -07:00
2018-07-24 19:11:26 +02:00
2017-08-07 17:22:14 +02:00
2014-12-31 13:06:50 -05:00
2018-07-12 10:04:29 -04:00
2014-10-09 11:35:48 +03:00
2017-11-13 01:41:20 +01:00
2018-07-27 09:57:23 +10:00
2019-05-31 06:46:18 -07:00
2018-06-28 20:32:51 +09:00
2010-02-09 11:13:56 +01:00
2018-03-26 08:53:43 -06:00
2018-08-08 11:06:20 +02:00
2018-06-22 13:43:27 +09:00
2014-03-13 12:11:00 +10:30
2019-05-22 07:37:44 +02:00
2018-04-11 10:28:38 -07:00
2018-07-12 21:35:28 +02:00
2019-05-16 19:41:22 +02:00
2017-12-01 13:09:40 -08:00
2018-04-12 09:41:19 -07:00
2017-02-24 17:46:57 -08:00
2017-08-28 20:51:22 +02:00
2018-06-05 08:50:16 -04:00
2018-06-07 17:34:35 -07:00
2018-04-11 10:28:32 -07:00
2019-05-04 09:20:11 +02:00
2018-06-07 17:34:39 -07:00
2018-03-26 13:14:43 -04:00
2018-08-22 10:52:45 -07:00
2018-01-28 22:17:24 -05:00
2018-01-31 17:18:37 -08:00
2017-11-09 10:23:28 +01:00
2018-07-25 13:41:22 -07:00
2018-07-21 10:43:12 -05:00
2017-12-16 02:05:48 +01:00
2018-08-22 10:52:46 -07:00
2019-06-11 12:20:52 +02:00
2018-07-20 01:11:45 +02:00
2018-08-02 17:33:06 -04:00
2018-08-02 17:16:05 +02:00
2018-07-07 17:25:23 +02:00
2018-08-16 12:14:42 -07:00
2018-01-15 12:07:46 -08:00
2019-04-17 08:38:45 +02:00
2013-04-30 15:50:12 +05:30
2018-06-20 11:35:56 +02:00
2018-02-06 18:32:47 -08:00
2018-11-13 11:08:51 -08:00
2019-06-17 19:51:56 +02:00
2015-10-01 09:57:59 -07:00
2018-02-06 18:32:44 -08:00
2017-12-20 09:53:54 -07:00
2018-05-14 09:51:34 -04:00
2017-08-15 09:02:07 -07:00
2013-10-17 15:53:09 -04:00
2017-08-15 09:02:08 -07:00