aux/draw: fix memory leak related to ureg_get_tokens()
authorPatrick Lerda <patrick9876@free.fr>
Wed, 8 Mar 2023 20:27:57 +0000 (21:27 +0100)
committerMarge Bot <emma+marge@anholt.net>
Tue, 25 Apr 2023 20:04:43 +0000 (20:04 +0000)
Indeed, the function nir_to_tgsi() returns an ureg_get_tokens() allocated
object which is assigned locally. The ureg_get_tokens() allocated object
should be freed.

For instance, this issue is triggered with a llvm enabled lima,
"piglit/bin/gl-1.0-rendermode-feedback -auto -fbo":
Direct leak of 512 byte(s) in 1 object(s) allocated from:
    #0 0x7faeaa4500 in __interceptor_realloc (/usr/lib64/libasan.so.6+0xa4500)
    #1 0x7fa4a88f1c in tokens_expand ../src/gallium/auxiliary/tgsi/tgsi_ureg.c:239
    #2 0x7fa4a88f1c in get_tokens ../src/gallium/auxiliary/tgsi/tgsi_ureg.c:262
    #3 0x7fa4a900f4 in copy_instructions ../src/gallium/auxiliary/tgsi/tgsi_ureg.c:2079
    #4 0x7fa4a900f4 in ureg_finalize ../src/gallium/auxiliary/tgsi/tgsi_ureg.c:2129
    #5 0x7fa4a91dfc in ureg_get_tokens ../src/gallium/auxiliary/tgsi/tgsi_ureg.c:2206
    #6 0x7fa4b20a2c in nir_to_tgsi_options ../src/gallium/auxiliary/nir/nir_to_tgsi.c:4011
    #7 0x7fa4a0c914 in draw_create_vertex_shader ../src/gallium/auxiliary/draw/draw_vs.c:77

Fixes: b5e782f5f431 ("aux/draw: use nir_to_tgsi for draw shader in llvm path")
Signed-off-by: Patrick Lerda <patrick9876@free.fr>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21924>

src/gallium/auxiliary/draw/draw_vs.c

index bdd886f..e5d88c6 100644 (file)
@@ -47,6 +47,7 @@
 
 #include "tgsi/tgsi_dump.h"
 #include "tgsi/tgsi_exec.h"
+#include "tgsi/tgsi_ureg.h"
 
 #include "nir/nir_to_tgsi.h"
 
@@ -65,6 +66,7 @@ draw_create_vertex_shader(struct draw_context *draw,
    }
 
 #ifdef DRAW_LLVM_AVAILABLE
+   bool is_allocated = false;
    if (draw->pt.middle.llvm) {
       struct pipe_screen *screen = draw->pipe->screen;
       if (shader->type == PIPE_SHADER_IR_NIR &&
@@ -75,6 +77,7 @@ draw_create_vertex_shader(struct draw_context *draw,
             PIPE_SHADER_IR_TGSI))) {
         state.type = PIPE_SHADER_IR_TGSI;
         state.tokens = nir_to_tgsi(shader->ir.nir, screen);
+        is_allocated = true;
       }
       vs = draw_create_vs_llvm(draw, &state);
    }
@@ -84,6 +87,12 @@ draw_create_vertex_shader(struct draw_context *draw,
       vs = draw_create_vs_exec(draw, &state);
    }
 
+#ifdef DRAW_LLVM_AVAILABLE
+   if (is_allocated) {
+      ureg_free_tokens(state.tokens);
+   }
+#endif
+
    if (vs) {
       bool found_clipvertex = FALSE;
       vs->position_output = -1;