diff options
author | Jason Gunthorpe <jgg@mellanox.com> | 2019-05-23 11:40:24 -0300 |
---|---|---|
committer | Jason Gunthorpe <jgg@mellanox.com> | 2019-06-24 17:38:18 -0300 |
commit | 2dcc3eb8ab50c9ca816cc60abfd94bea559d3e86 (patch) | |
tree | f993a20fd2e73d85bbb61d1ba118eac9ae5410f5 | |
parent | 187229c2ddd12a5bb5cd6bb3fbef9ecbc6eead92 (diff) | |
download | linux-2dcc3eb8ab50c9ca816cc60abfd94bea559d3e86.tar.gz linux-2dcc3eb8ab50c9ca816cc60abfd94bea559d3e86.tar.bz2 linux-2dcc3eb8ab50c9ca816cc60abfd94bea559d3e86.zip |
mm/hmm: Poison hmm_range during unregister
Trying to misuse a range outside its lifetime is a kernel bug. Use poison
bytes to help detect this condition. Double unregister will reliably crash.
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Reviewed-by: Jérôme Glisse <jglisse@redhat.com>
Reviewed-by: John Hubbard <jhubbard@nvidia.com>
Acked-by: Souptick Joarder <jrdr.linux@gmail.com>
Reviewed-by: Ralph Campbell <rcampbell@nvidia.com>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Tested-by: Philip Yang <Philip.Yang@amd.com>
-rw-r--r-- | mm/hmm.c | 14 |
1 files changed, 8 insertions, 6 deletions
@@ -925,19 +925,21 @@ void hmm_range_unregister(struct hmm_range *range) { struct hmm *hmm = range->hmm; - /* Sanity check this really should not happen. */ - if (hmm == NULL || range->end <= range->start) - return; - mutex_lock(&hmm->lock); list_del_init(&range->list); mutex_unlock(&hmm->lock); /* Drop reference taken by hmm_range_register() */ - range->valid = false; mmput(hmm->mm); hmm_put(hmm); - range->hmm = NULL; + + /* + * The range is now invalid and the ref on the hmm is dropped, so + * poison the pointer. Leave other fields in place, for the caller's + * use. + */ + range->valid = false; + memset(&range->hmm, POISON_INUSE, sizeof(range->hmm)); } EXPORT_SYMBOL(hmm_range_unregister); |