mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-05 19:31:57 -04:00
msm:adsprpc: Fix UAF of ctx->perf in async invoke perf counter
In async invoke path, fastrpc_update_invoke_count is called at invoke_end with perf_counter pointing into ctx->perf. After fastrpc_invoke_send returns, the async response thread may call context_free(ctx), freeing ctx->perf before invoke_end. This causes a use-after-free write that corrupts the SLUB freelist and may trigger a kernel panic on next allocation. Fix by storing submission timestamp in ctx->invoke_start_time before send, removing unsafe call from invoke_end, and moving fastrpc_update_invoke_count to fastrpc_wait_on_async_queue. There, ctx is guaranteed valid before context_free. This also aligns async perf->invoke with sync, measuring full end-to-end latency instead of submission-only latency. Acked-by: Sharad Kumar <sharku@qti.qualcomm.com> Change-Id: I91f2a2479b508fde2fe7c26783ee56dc9391eb17 Signed-off-by: Santosh Sakore <ssakore@qti.qualcomm.com>
This commit is contained in:
parent
486d7b2d1e
commit
c2adf7dc3f
1 changed files with 20 additions and 4 deletions
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
/* Uncomment this block to log an error on every VERIFY failure */
|
||||
|
|
@ -444,6 +444,7 @@ struct smq_invoke_ctx {
|
|||
uint32_t sc_interrupted;
|
||||
struct fastrpc_file *fl_interrupted;
|
||||
uint32_t handle_interrupted;
|
||||
struct timespec64 invoke_start_time; /* submission timestamp for async perf */
|
||||
};
|
||||
|
||||
struct fastrpc_ctx_lst {
|
||||
|
|
@ -3362,6 +3363,15 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
|
|||
inv_args(ctx);
|
||||
PERF_END);
|
||||
|
||||
/*
|
||||
* Store submission timestamp in ctx before sending to DSP.
|
||||
* For async invokes, perf->invoke will be updated in the collector
|
||||
* thread (fastrpc_wait_on_async_queue) where ctx is still valid,
|
||||
* measuring full end-to-end latency consistent with the sync path.
|
||||
*/
|
||||
if (fl->profile && isasyncinvoke)
|
||||
ctx->invoke_start_time = invoket;
|
||||
|
||||
PERF(fl->profile, GET_COUNTER(perf_counter, PERF_LINK),
|
||||
VERIFY(err, 0 == (err = fastrpc_invoke_send(ctx,
|
||||
kernel, invoke->handle)));
|
||||
|
|
@ -3423,9 +3433,6 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
|
|||
err = -ECONNRESET;
|
||||
|
||||
invoke_end:
|
||||
if (fl->profile && !interrupted && isasyncinvoke)
|
||||
fastrpc_update_invoke_count(invoke->handle, perf_counter,
|
||||
&invoket);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -3495,6 +3502,15 @@ bail:
|
|||
async_res->result = ierr;
|
||||
if (ctx) {
|
||||
if (fl->profile && ctx->perf && ctx->handle > FASTRPC_STATIC_HANDLE_MAX) {
|
||||
/*
|
||||
* Update invoke/count perf counters here where ctx->perf is
|
||||
* guaranteed valid. This measures full end-to-end async latency
|
||||
* (submit → DSP → collect), consistent with the sync path.
|
||||
* invoke_start_time was stored in ctx before fastrpc_invoke_send
|
||||
* in fastrpc_internal_invoke.
|
||||
*/
|
||||
fastrpc_update_invoke_count(ctx->handle, perf_counter,
|
||||
&ctx->invoke_start_time);
|
||||
trace_fastrpc_perf_counters(ctx->handle, ctx->sc,
|
||||
ctx->perf->count, ctx->perf->flush, ctx->perf->map,
|
||||
ctx->perf->copy, ctx->perf->link, ctx->perf->getargs,
|
||||
|
|
|
|||
Loading…
Reference in a new issue