diff options
author | Todd Frederick <tfred@google.com> | 2023-08-12 21:02:15 +0000 |
---|---|---|
committer | Todd Frederick <tfred@google.com> | 2023-08-13 20:42:16 +0000 |
commit | eaa359f757545f9f1624b46e981954bdc910d71e (patch) | |
tree | 31c7a31fcb96ff1e935640c404e0db5089c3d35e | |
parent | 21e02ada5775657df72ba99e93c7fe57421eb228 (diff) | |
download | exynos-android-exynos-r11-4.19-rvc-wear-jr3-qpr2-dr.tar.gz |
gpu: r29p0: CVE-2023-4211android-wear-11.0.0_r0.13android-exynos-r11-4.19-rvc-wear-jr3-qpr2-dr
Bug: 294574473
Bug: 295041809
Change-Id: I26f71a29059a689e80de6a895bf3e5d83e77f5fd
Signed-off-by: Todd Frederick <tfred@google.com>
-rw-r--r-- | drivers/gpu/arm/t72x/r29p0/mali_kbase_context.c | 32 | ||||
-rw-r--r-- | drivers/gpu/arm/t72x/r29p0/mali_kbase_defs.h | 15 | ||||
-rw-r--r-- | drivers/gpu/arm/t72x/r29p0/mali_kbase_mem_linux.c | 65 |
3 files changed, 33 insertions, 79 deletions
diff --git a/drivers/gpu/arm/t72x/r29p0/mali_kbase_context.c b/drivers/gpu/arm/t72x/r29p0/mali_kbase_context.c index 195914a8cf99..b51922179b0e 100644 --- a/drivers/gpu/arm/t72x/r29p0/mali_kbase_context.c +++ b/drivers/gpu/arm/t72x/r29p0/mali_kbase_context.c @@ -72,22 +72,28 @@ kbase_create_context(struct kbase_device *kbdev, bool is_compat, atomic_set(&kctx->setup_complete, 0); atomic_set(&kctx->setup_in_progress, 0); - spin_lock_init(&kctx->mm_update_lock); kctx->process_mm = NULL; atomic_set(&kctx->nonmapped_pages, 0); kctx->slots_pullable = 0; kctx->tgid = current->tgid; kctx->pid = current->pid; - - rcu_read_lock(); - pid_struct = find_get_pid(kctx->tgid); - task = pid_task(pid_struct, PIDTYPE_PID); - get_task_struct(task); - kctx->task = task; - put_pid(pid_struct); - rcu_read_unlock(); - + /* Check if this is a Userspace created context */ + if (likely(kctx->filp)) { + rcu_read_lock(); + pid_struct = find_get_pid(kctx->tgid); + task = pid_task(pid_struct, PIDTYPE_PID); + get_task_struct(task); + kctx->task = task; + put_pid(pid_struct); + rcu_read_unlock(); + /* This merely takes a reference on the mm_struct and not on the + * address space and so won't block the freeing of address space + * on process exit. + */ + mmgrab(current->mm); + kctx->process_mm = current->mm; + } err = kbase_mem_pool_init(&kctx->mem_pool, kbdev->mem_pool_max_size_default, @@ -345,8 +351,10 @@ void kbase_destroy_context(struct kbase_context *kctx) kctx->ctx_need_qos = false; } - - put_task_struct(kctx->task); + if (likely(kctx->filp)) { + mmdrop(kctx->process_mm); + put_task_struct(kctx->task); + } vfree(kctx); /* MALI_SEC_INTEGRATION */ diff --git a/drivers/gpu/arm/t72x/r29p0/mali_kbase_defs.h b/drivers/gpu/arm/t72x/r29p0/mali_kbase_defs.h index 528a0425f427..640fd5636ee1 100644 --- a/drivers/gpu/arm/t72x/r29p0/mali_kbase_defs.h +++ b/drivers/gpu/arm/t72x/r29p0/mali_kbase_defs.h @@ -1974,7 +1974,11 @@ struct kbase_reg_zone { * @process_mm: Pointer to the memory descriptor of the process which * created the context. Used for accounting the physical * pages used for GPU allocations, done for the context, - * to the memory consumed by the process. + * to the memory consumed by the process. A reference is + * taken on this descriptor for the Userspace created + * contexts so that Kbase can safely access it to update + * the memory usage counters. The reference is dropped on + * context termination. * @gpu_va_end: End address of the GPU va space (in 4KB page units) * @jit_va: Indicates if a JIT_VA zone has been created. * @timeline: Object tracking the number of atoms currently in flight for @@ -2138,14 +2142,7 @@ struct kbase_context { atomic_t refcount; - /* NOTE: - * - * Flags are in jctx.sched_info.ctx.flags - * Mutable flags *must* be accessed under jctx.sched_info.ctx.jsctx_mutex - * - * All other flags must be added there */ - spinlock_t mm_update_lock; - struct mm_struct __rcu *process_mm; + struct mm_struct *process_mm; u64 gpu_va_end; bool jit_va; diff --git a/drivers/gpu/arm/t72x/r29p0/mali_kbase_mem_linux.c b/drivers/gpu/arm/t72x/r29p0/mali_kbase_mem_linux.c index 7cdf510eed9a..2d40764df241 100644 --- a/drivers/gpu/arm/t72x/r29p0/mali_kbase_mem_linux.c +++ b/drivers/gpu/arm/t72x/r29p0/mali_kbase_mem_linux.c @@ -2502,73 +2502,25 @@ KBASE_EXPORT_TEST_API(kbase_vunmap); void kbasep_os_process_page_usage_update(struct kbase_context *kctx, int pages) { - struct mm_struct *mm; + struct mm_struct *mm = kctx->process_mm; - rcu_read_lock(); - mm = rcu_dereference(kctx->process_mm); - if (mm) { - atomic_add(pages, &kctx->nonmapped_pages); -#ifdef SPLIT_RSS_COUNTING - add_mm_counter(mm, MM_FILEPAGES, pages); -#else - spin_lock(&mm->page_table_lock); - add_mm_counter(mm, MM_FILEPAGES, pages); - spin_unlock(&mm->page_table_lock); -#endif - } - rcu_read_unlock(); -} - -static void kbasep_os_process_page_usage_drain(struct kbase_context *kctx) -{ - int pages; - struct mm_struct *mm; - - spin_lock(&kctx->mm_update_lock); - mm = rcu_dereference_protected(kctx->process_mm, lockdep_is_held(&kctx->mm_update_lock)); - if (!mm) { - spin_unlock(&kctx->mm_update_lock); + if (unlikely(!mm)) { return; } - - rcu_assign_pointer(kctx->process_mm, NULL); - spin_unlock(&kctx->mm_update_lock); - synchronize_rcu(); - - pages = atomic_xchg(&kctx->nonmapped_pages, 0); + atomic_add(pages, &kctx->nonmapped_pages); #ifdef SPLIT_RSS_COUNTING - add_mm_counter(mm, MM_FILEPAGES, -pages); + add_mm_counter(mm, MM_FILEPAGES, pages); #else spin_lock(&mm->page_table_lock); - add_mm_counter(mm, MM_FILEPAGES, -pages); + add_mm_counter(mm, MM_FILEPAGES, pages); spin_unlock(&mm->page_table_lock); #endif } -static void kbase_special_vm_close(struct vm_area_struct *vma) -{ - struct kbase_context *kctx; - - kctx = vma->vm_private_data; - kbasep_os_process_page_usage_drain(kctx); -} - -static const struct vm_operations_struct kbase_vm_special_ops = { - .close = kbase_special_vm_close, -}; - static int kbase_tracking_page_setup(struct kbase_context *kctx, struct vm_area_struct *vma) { - /* check that this is the only tracking page */ - spin_lock(&kctx->mm_update_lock); - if (rcu_dereference_protected(kctx->process_mm, lockdep_is_held(&kctx->mm_update_lock))) { - spin_unlock(&kctx->mm_update_lock); - return -EFAULT; - } - - rcu_assign_pointer(kctx->process_mm, current->mm); - - spin_unlock(&kctx->mm_update_lock); + if (vma_pages(vma) != 1) + return -EINVAL; /* no real access */ vma->vm_flags &= ~(VM_READ | VM_MAYREAD | VM_WRITE | VM_MAYWRITE | VM_EXEC | VM_MAYEXEC); @@ -2577,9 +2529,6 @@ static int kbase_tracking_page_setup(struct kbase_context *kctx, struct vm_area_ #else vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED | VM_IO; #endif - vma->vm_ops = &kbase_vm_special_ops; - vma->vm_private_data = kctx; - return 0; } |