asahi: Fix use-after-free in shader key

We need to take ownership of shader keys before we can insert them into
the hash table. Caught by ASan.

==6343==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x00016bc51410 at pc 0x00010498d6cc bp 0x00016bc50240 sp 0x00016bc4f9d0
READ of size 592 at 0x00016bc51410 thread T0
    #0 0x10498d6c8 in MemcmpInterceptorCommon(void*, int (*)(void const*, void const*, unsigned long), void const*, void const*, unsigned long)+0x208 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x196c8)
    #1 0x10498da08 in wrap_memcmp+0x98 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x19a08)
    #2 0x10b7f3f18 in asahi_shader_key_equal agx_state.c:867
    #3 0x10a482e7c in hash_table_search hash_table.c:325
    #4 0x10b7f4e94 in agx_update_shader agx_state.c:899
    #5 0x10b7f0dc4 in agx_draw_vbo agx_state.c:1590
    #6 0x10a7c28c4 in u_vbuf_draw_vbo u_vbuf.c:1498
    #7 0x10a5db03c in cso_multi_draw cso_context.c:1639
    #8 0x10aed03d0 in _mesa_validated_drawrangeelements draw.c:1812
    #9 0x10aed08d4 in _mesa_DrawElements draw.c:1945

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15109>
This commit is contained in:
Alyssa Rosenzweig 2022-02-21 11:50:59 -05:00
parent ed246aa29b
commit 694fe73976

View file

@ -889,6 +889,7 @@ agx_create_shader_state(struct pipe_context *pctx,
return so;
}
/* Does not take ownership of key. Clones if necessary. */
static bool
agx_update_shader(struct agx_context *ctx, struct agx_compiled_shader **out,
enum pipe_shader_type stage, struct asahi_shader_key *key)
@ -967,7 +968,13 @@ agx_update_shader(struct agx_context *ctx, struct agx_compiled_shader **out,
ralloc_free(nir);
util_dynarray_fini(&binary);
he = _mesa_hash_table_insert(so->variants, key, compiled);
/* key may be destroyed after we return, so clone it before using it as a
* hash table key. The clone is logically owned by the hash table.
*/
struct asahi_shader_key *cloned_key = ralloc(so->variants, struct asahi_shader_key);
memcpy(cloned_key, key, sizeof(struct asahi_shader_key));
he = _mesa_hash_table_insert(so->variants, cloned_key, compiled);
*out = he->data;
return true;
}