From: Alex Deucher <alexander.deuc...@amd.com>

Check access to the fb scratch array to avoid accessing
memory past the end of the array.

Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
Cc: stable at kernel.org
---
 drivers/gpu/drm/radeon/atom.c |   15 +++++++++++++--
 drivers/gpu/drm/radeon/atom.h |    1 +
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index e88c644..f69b852 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -277,7 +277,12 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, 
uint8_t attr,
        case ATOM_ARG_FB:
                idx = U8(*ptr);
                (*ptr)++;
-               val = gctx->scratch[((gctx->fb_base + idx) / 4)];
+               if ((gctx->fb_base + idx) > gctx->scratch_size_bytes) {
+                       DRM_DEBUG_KMS("ATOM: fb read beyond scratch region: %d 
vs. %d\n",
+                                     gctx->fb_base + idx, 
gctx->scratch_size_bytes);
+                       val = 0;
+               } else
+                       val = gctx->scratch[((gctx->fb_base + idx) / 4)];
                if (print)
                        DEBUG("FB[0x%02X]", idx);
                break;
@@ -531,7 +536,11 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, 
uint8_t attr,
        case ATOM_ARG_FB:
                idx = U8(*ptr);
                (*ptr)++;
-               gctx->scratch[((gctx->fb_base + idx) / 4)] = val;
+               if ((gctx->fb_base + idx) > gctx->scratch_size_bytes) {
+                       DRM_DEBUG_KMS("ATOM: fb write beyond scratch region: %d 
vs. %d\n",
+                                     gctx->fb_base + idx, 
gctx->scratch_size_bytes);
+               } else
+                       gctx->scratch[((gctx->fb_base + idx) / 4)] = val;
                DEBUG("FB[0x%02X]", idx);
                break;
        case ATOM_ARG_PLL:
@@ -1370,11 +1379,13 @@ int atom_allocate_fb_scratch(struct atom_context *ctx)

                usage_bytes = 
firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
        }
+       ctx->scratch_size_bytes = 0;
        if (usage_bytes == 0)
                usage_bytes = 20 * 1024;
        /* allocate some scratch memory */
        ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
        if (!ctx->scratch)
                return -ENOMEM;
+       ctx->scratch_size_bytes = usage_bytes;
        return 0;
 }
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h
index a589a55..93cfe20 100644
--- a/drivers/gpu/drm/radeon/atom.h
+++ b/drivers/gpu/drm/radeon/atom.h
@@ -137,6 +137,7 @@ struct atom_context {
        int cs_equal, cs_above;
        int io_mode;
        uint32_t *scratch;
+       int scratch_size_bytes;
 };

 extern int atom_debug;
-- 
1.7.1.1

Reply via email to