fastrpc_get_args() computes inline payload spans from 64-bit user
buffer ranges, but stores each span in an int before comparing it with
the remaining DMA buffer space.

A large span can truncate before the bounds check and advance the DMA
write cursor by the wrong amount. Keep the span 64-bit and fail the
invoke when the serialized payload would exceed the buffer.

Signed-off-by: Yousef Alhouseen <[email protected]>
---
 drivers/misc/fastrpc.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 42fc128e1..8dd8315d5 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1079,7 +1079,7 @@ static int fastrpc_get_args(u32 kernel, struct 
fastrpc_invoke_ctx *ctx)
        ctx->rpra = rpra;
 
        for (oix = 0; oix < ctx->nbufs; ++oix) {
-               int mlen;
+               u64 mlen;
 
                i = ctx->olaps[oix].raix;
                len = ctx->args[i].length;
@@ -1119,8 +1119,10 @@ static int fastrpc_get_args(u32 kernel, struct 
fastrpc_invoke_ctx *ctx)
 
                        mlen = ctx->olaps[oix].mend - ctx->olaps[oix].mstart;
 
-                       if (rlen < mlen)
+                       if (rlen < mlen) {
+                               err = -EOVERFLOW;
                                goto bail;
+                       }
 
                        rpra[i].buf.pv = args - ctx->olaps[oix].offset;
                        pages[i].addr = ctx->buf->dma_addr -
-- 
2.54.0

Reply via email to