mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 15:11:48 -04:00
BACKPORT: dsp-kernel: Separate overlap handling for ION and non-ION buffers
Currently, overlap calculation did not distinguish between ION and non-ION buffers. This could result in incorrect offsets when an ION buffer overlapped with a non-ION buffer, leading to out-of-bounds writes and potential security issues. Calculate overlap ranges separately for ION and non-ION buffers. Change-Id: If5eb57d447b68d58d8821ecfbf2d9375b2cd1f8e Signed-off-by: Ramesh Nallagopu <quic_rnallago@quicinc.com>
This commit is contained in:
parent
28e935c7d0
commit
5920e58e41
1 changed files with 25 additions and 8 deletions
|
|
@ -379,9 +379,21 @@ static int olaps_cmp(const void *a, const void *b)
|
|||
return st == 0 ? ed : st;
|
||||
}
|
||||
|
||||
/**
|
||||
* fastrpc_get_buff_overlaps - Detect and handle buffer overlaps in RPC args
|
||||
* @ctx: The invoke context containing buffer information
|
||||
*
|
||||
* This function detects overlapping memory regions in the RPC arguments and
|
||||
* adjusts the memory mapping accordingly. It handles ION and non-ION buffers
|
||||
* separately to prevent incorrect overlap detection between different buf types.
|
||||
* For each buffer type:
|
||||
* - If a buffer overlaps with a previous buffer of the same type, it adjusts
|
||||
* the mapping to avoid the overlap
|
||||
* - If no overlap is detected, it uses the full buffer range
|
||||
*/
|
||||
static void fastrpc_get_buff_overlaps(struct fastrpc_invoke_ctx *ctx)
|
||||
{
|
||||
u64 max_end = 0;
|
||||
u64 ion_buf_end_pos = 0, non_ion_buf_end_pos = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ctx->nbufs; ++i) {
|
||||
|
|
@ -393,24 +405,29 @@ static void fastrpc_get_buff_overlaps(struct fastrpc_invoke_ctx *ctx)
|
|||
sort(ctx->olaps, ctx->nbufs, sizeof(*ctx->olaps), olaps_cmp, NULL);
|
||||
|
||||
for (i = 0; i < ctx->nbufs; ++i) {
|
||||
/* Falling inside previous range */
|
||||
if (ctx->olaps[i].start < max_end) {
|
||||
ctx->olaps[i].mstart = max_end;
|
||||
ctx->olaps[i].mend = ctx->olaps[i].end;
|
||||
ctx->olaps[i].offset = max_end - ctx->olaps[i].start;
|
||||
/* Separate ION and non-ION buffers; fd <= 0 indicates non-ION */
|
||||
u64 *last_buf_end = (ctx->args[ctx->olaps[i].raix].fd <= 0) ?
|
||||
&non_ion_buf_end_pos : &ion_buf_end_pos;
|
||||
|
||||
if (ctx->olaps[i].end > max_end) {
|
||||
max_end = ctx->olaps[i].end;
|
||||
if (ctx->olaps[i].start < *last_buf_end) {
|
||||
/* Overlap detected within same buffer type */
|
||||
ctx->olaps[i].mstart = *last_buf_end;
|
||||
ctx->olaps[i].mend = ctx->olaps[i].end;
|
||||
ctx->olaps[i].offset = *last_buf_end - ctx->olaps[i].start;
|
||||
|
||||
if (ctx->olaps[i].end > *last_buf_end) {
|
||||
*last_buf_end = ctx->olaps[i].end;
|
||||
} else {
|
||||
ctx->olaps[i].mend = 0;
|
||||
ctx->olaps[i].mstart = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* No overlap, assign full range */
|
||||
ctx->olaps[i].mend = ctx->olaps[i].end;
|
||||
ctx->olaps[i].mstart = ctx->olaps[i].start;
|
||||
ctx->olaps[i].offset = 0;
|
||||
max_end = ctx->olaps[i].end;
|
||||
*last_buf_end = ctx->olaps[i].end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue