diff options
author | Varad Gautam <varadgautam@google.com> | 2022-07-03 17:09:36 +0000 |
---|---|---|
committer | Varad Gautam <varadgautam@google.com> | 2022-07-04 11:36:36 +0000 |
commit | 8cf6f3dab19f0b0a2bad43c1385bb957c76c6752 (patch) | |
tree | bc51953541c9dbf0c1a8f16304635b003b7dfaed | |
parent | bce3f96102d290ce5f0c7bcee90f4211998b9075 (diff) | |
download | gpu-8cf6f3dab19f0b0a2bad43c1385bb957c76c6752.tar.gz |
mali_kbase: csf: Prevent kthread leak in kbase_csf_ctx_init error path
kbase_csf_ctx_init() creates and wakes up a realtime kthread
(mali_submit) and continues on to initialize csf context. The
kthread_worker arg passed to kthread_work_fn() for mali_submit lives
within the associated kctx (kctx->csf.pending_submission_worker).
If csf context initialization fails, kbase_csf_ctx_init() returns to
kbase_create_context(), which frees the associated kctx via
kbase_context_term_partial().
This leads to the following race between kctx free and the
kthread_worker arg access by mali_submit's kthread_worker_fn call:
T1(kbase_create_context): T2(mali_submit):
kbase_csf_ctx_init()
kbase_create_realtime_thread("mali_submit")
kthread_create(kthread_worker_fn)
wake_up_process()
err = kbase_csf_scheduler_context_init() // -ENOMEM
destroy_workqueue(kctx->csf.wq);
kbase_context_term_partial()
kbase_context_free()
vfree(kctx)
kthread_worker_fn()
WARN_ON(worker->task &&
worker->task != current)
// worker is invalid, oops
Stop mali_submit kthread before erroring out from kbase_csf_ctx_init()
to close this race.
Bug: 234054582
Test: Forced -ENOMEM from kbase_csf_scheduler_context_init. The kernel
crashed within 5mins of boot without this patch, and survives with it.
Change-Id: I1c31ea7c0c914d7ca84630cb7fd1e20b6595d69c
Signed-off-by: Varad Gautam <varadgautam@google.com>
-rw-r--r-- | mali_kbase/csf/mali_kbase_csf.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/mali_kbase/csf/mali_kbase_csf.c b/mali_kbase/csf/mali_kbase_csf.c index 0fe8160..d045df8 100644 --- a/mali_kbase/csf/mali_kbase_csf.c +++ b/mali_kbase/csf/mali_kbase_csf.c @@ -1765,7 +1765,7 @@ int kbase_csf_ctx_init(struct kbase_context *kctx) err = kbase_csf_scheduler_context_init(kctx); if (unlikely(err)) - goto out_err_kthread; + goto out_err_scheduler_context; err = kbase_csf_kcpu_queue_context_init(kctx); if (unlikely(err)) @@ -1785,6 +1785,8 @@ out_err_tiler_heap_context: kbase_csf_kcpu_queue_context_term(kctx); out_err_kcpu_queue_context: kbase_csf_scheduler_context_term(kctx); +out_err_scheduler_context: + kthread_stop(kctx->csf.pending_sub_worker_thread); out_err_kthread: destroy_workqueue(kctx->csf.wq); out: |