amdxdna_umap_release() calls the blocking mmu_interval_notifier_remove()
before removing the object from abo->mem.umap_list. If
aie2_populate_range() runs concurrently, it may obtain a reference to an
amdxdna_umap that is being released, leading to a potential use-after-free.

Use refcount_inc_not_zero() in aie2_populate_range() when acquiring a
reference. If the reference count has already dropped to zero, release
is in progress and the entry is skipped.

Fixes: e486147c912f ("accel/amdxdna: Add BO import and export")
Signed-off-by: Lizhi Hou <[email protected]>
---
 drivers/accel/amdxdna/aie2_ctx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/accel/amdxdna/aie2_ctx.c b/drivers/accel/amdxdna/aie2_ctx.c
index 408ff7e2a272..7bf635634e64 100644
--- a/drivers/accel/amdxdna/aie2_ctx.c
+++ b/drivers/accel/amdxdna/aie2_ctx.c
@@ -1039,7 +1039,7 @@ static int aie2_populate_range(struct amdxdna_gem_obj 
*abo)
        found = false;
        down_write(&xdna->notifier_lock);
        list_for_each_entry(mapp, &abo->mem.umap_list, node) {
-               if (mapp->invalid) {
+               if (mapp->invalid && kref_get_unless_zero(&mapp->refcnt)) {
                        found = true;
                        break;
                }
@@ -1050,7 +1050,7 @@ static int aie2_populate_range(struct amdxdna_gem_obj 
*abo)
                up_write(&xdna->notifier_lock);
                return 0;
        }
-       kref_get(&mapp->refcnt);
+
        up_write(&xdna->notifier_lock);
 
        mm = mapp->notifier.mm;
-- 
2.34.1

Reply via email to