diff options
author | Jason Gunthorpe <jgg@mellanox.com> | 2019-05-22 16:52:52 -0300 |
---|---|---|
committer | Jason Gunthorpe <jgg@mellanox.com> | 2019-06-07 10:47:24 -0300 |
commit | 6d7c3cde93c1d9ac0b37f78ec3f2ff052159a242 (patch) | |
tree | a3b28f3ceb1a253b2683b8cb04002f6cccf2958f /mm/memory.c | |
parent | 9b1ae605c8e295836050fa6eaf720131db2fac73 (diff) | |
download | linux-6d7c3cde93c1d9ac0b37f78ec3f2ff052159a242.tar.bz2 |
mm/hmm: fix use after free with struct hmm in the mmu notifiers
mmu_notifier_unregister_no_release() is not a fence and the mmu_notifier
system will continue to reference hmm->mn until the srcu grace period
expires.
Resulting in use after free races like this:
CPU0 CPU1
__mmu_notifier_invalidate_range_start()
srcu_read_lock
hlist_for_each ()
// mn == hmm->mn
hmm_mirror_unregister()
hmm_put()
hmm_free()
mmu_notifier_unregister_no_release()
hlist_del_init_rcu(hmm-mn->list)
mn->ops->invalidate_range_start(mn, range);
mm_get_hmm()
mm->hmm = NULL;
kfree(hmm)
mutex_lock(&hmm->lock);
Use SRCU to kfree the hmm memory so that the notifiers can rely on hmm
existing. Get the now-safe hmm struct through container_of and directly
check kref_get_unless_zero to lock it against free.
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Reviewed-by: John Hubbard <jhubbard@nvidia.com>
Reviewed-by: Ralph Campbell <rcampbell@nvidia.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Tested-by: Philip Yang <Philip.Yang@amd.com>
Diffstat (limited to 'mm/memory.c')
0 files changed, 0 insertions, 0 deletions