From 2b7453f47862b0ae8032ba269b40830a34a6fb43 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 21 Mar 2017 10:01:02 -0400 Subject: [PATCH] freedreno: fix potential use-after-free on a5xx+ Something that valgrind spotted: ==8441== Invalid read of size 4 ==8441== at 0x5DEE168: msm_ringbuffer_emit_reloc (msm_ringbuffer.c:506) ==8441== by 0x5B48F0F: OUT_RELOCW (freedreno_util.h:241) ==8441== by 0x5B48F0F: fd5_emit_blit (fd5_emit.h:131) ==8441== by 0x5B48F0F: emit_gmem2mem_surf.isra.12 (fd5_gmem.c:450) ==8441== by 0x5B4910F: fd5_emit_tile_gmem2mem (fd5_gmem.c:477) ==8441== by 0x5B14943: render_tiles (freedreno_gmem.c:342) ==8441== by 0x5B14943: fd_gmem_render_tiles (freedreno_gmem.c:416) ==8441== by 0x5B0FBA7: batch_flush (freedreno_batch.c:281) ==8441== by 0x5B0FBA7: fd_batch_flush (freedreno_batch.c:306) ==8441== by 0x5B11FE7: fd_context_flush (freedreno_context.c:52) ==8441== by 0x58AD783: st_glFlush (st_cb_flush.c:121) ==8441== by 0x5751EE7: _mesa_make_current (context.c:1652) ==8441== by 0x58E6A97: st_api_make_current (st_manager.c:811) ==8441== by 0x5A2CE43: dri_unbind_context (dri_context.c:207) ==8441== by 0x5A2C77F: driUnbindContext (dri_util.c:589) ==8441== by 0x4AC8A67: MakeContextCurrent (glxcurrent.c:214) ==8441== Address 0x6f5eb1c is 204 bytes inside a block of size 240 free'd ==8441== at 0x4868F44: realloc (vg_replace_malloc.c:785) ==8441== by 0x5DEE143: msm_ringbuffer_emit_reloc (msm_ringbuffer.c:502) ==8441== by 0x5B48F0F: OUT_RELOCW (freedreno_util.h:241) ==8441== by 0x5B48F0F: fd5_emit_blit (fd5_emit.h:131) ==8441== by 0x5B48F0F: emit_gmem2mem_surf.isra.12 (fd5_gmem.c:450) ==8441== by 0x5B4910F: fd5_emit_tile_gmem2mem (fd5_gmem.c:477) ==8441== by 0x5B14943: render_tiles (freedreno_gmem.c:342) ==8441== by 0x5B14943: fd_gmem_render_tiles (freedreno_gmem.c:416) ==8441== by 0x5B0FBA7: batch_flush (freedreno_batch.c:281) ==8441== by 0x5B0FBA7: fd_batch_flush (freedreno_batch.c:306) ==8441== by 0x5B11FE7: fd_context_flush (freedreno_context.c:52) ==8441== by 0x58AD783: st_glFlush (st_cb_flush.c:121) ==8441== by 0x5751EE7: _mesa_make_current (context.c:1652) ==8441== by 0x58E6A97: st_api_make_current (st_manager.c:811) ==8441== by 0x5A2CE43: dri_unbind_context (dri_context.c:207) ==8441== by 0x5A2C77F: driUnbindContext (dri_util.c:589) ==8441== Block was alloc'd at ==8441== at 0x4868F44: realloc (vg_replace_malloc.c:785) ==8441== by 0x5DEE08B: msm_ringbuffer_emit_reloc (msm_ringbuffer.c:481) ==8441== by 0x5B48F0F: OUT_RELOCW (freedreno_util.h:241) ==8441== by 0x5B48F0F: fd5_emit_blit (fd5_emit.h:131) ==8441== by 0x5B48F0F: emit_gmem2mem_surf.isra.12 (fd5_gmem.c:450) ==8441== by 0x5B4909F: fd5_emit_tile_gmem2mem (fd5_gmem.c:465) ==8441== by 0x5B14943: render_tiles (freedreno_gmem.c:342) ==8441== by 0x5B14943: fd_gmem_render_tiles (freedreno_gmem.c:416) ==8441== by 0x5B0FBA7: batch_flush (freedreno_batch.c:281) ==8441== by 0x5B0FBA7: fd_batch_flush (freedreno_batch.c:306) ==8441== by 0x5B11FE7: fd_context_flush (freedreno_context.c:52) ==8441== by 0x58AD783: st_glFlush (st_cb_flush.c:121) ==8441== by 0x5751EE7: _mesa_make_current (context.c:1652) ==8441== by 0x58E6A97: st_api_make_current (st_manager.c:811) ==8441== by 0x5A2CE43: dri_unbind_context (dri_context.c:207) ==8441== by 0x5A2C77F: driUnbindContext (dri_util.c:589) Signed-off-by: Rob Clark --- freedreno/msm/msm_ringbuffer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c index 17194f4c..c3b2eded 100644 --- a/freedreno/msm/msm_ringbuffer.c +++ b/freedreno/msm/msm_ringbuffer.c @@ -496,11 +496,16 @@ static void msm_ringbuffer_emit_reloc(struct fd_ringbuffer *ring, if (ring->pipe->gpu_id >= 500) { struct drm_msm_gem_submit_reloc *reloc_hi; + /* NOTE: grab reloc_idx *before* APPEND() since that could + * realloc() meaning that 'reloc' ptr is no longer valid: + */ + uint32_t reloc_idx = reloc->reloc_idx; + idx = APPEND(cmd, relocs); reloc_hi = &cmd->relocs[idx]; - reloc_hi->reloc_idx = reloc->reloc_idx; + reloc_hi->reloc_idx = reloc_idx; reloc_hi->reloc_offset = r->offset; reloc_hi->or = r->orhi; reloc_hi->shift = r->shift - 32;