<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Oct 27, 2016 at 1:30 PM, Eric Anholt <span dir="ltr"><<a href="mailto:eric@anholt.net" target="_blank">eric@anholt.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Fixes use-after-free-caused segfaults in the tgsi_to_nir() path.<br>
---<br>
<br>
I don't like the boolean I added here, any better plans, though?  I<br>
haven't fully piglited this, but it's enough to get gears to not crash<br>
on master (it at least touches the GLSL to NIR and TGSI to NIR paths.)<br></blockquote><div><br></div><div>I don't either. Let's consider the options...<br><br>Would it be better to simply make nir_shader_create() always allocate a shader_info and just memcpy old one if provided or zero it out if no shader info is provided?  Having a pointer which may or may not be parented to the nir_shader is a disaster waiting to happen.  Since the one provided to nir_shader_create() isn't required to be ralloc'd, we can't even use ralloc_parent() to check.<br><br></div><div>Another option would be to say that the NIR shader doesn't own the info ever. Maybe even get rid of the shader_info pointer in nir_shader.  It would probably mean manually passing the shader_info around a few more places, but it would work.<br><br></div><div>Tim, thoughts?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 src/compiler/nir/nir.c       |  2 ++<br>
 src/compiler/nir/nir.h       |  2 ++<br>
 src/compiler/nir/nir_clone.c | 14 +++++++++++++-<br>
 src/compiler/nir/nir_sweep.c |  3 +++<br>
 4 files changed, 20 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c<br>
index 09aad57e87f8..1448837d8fd1 100644<br>
--- a/src/compiler/nir/nir.c<br>
+++ b/src/compiler/nir/nir.c<br>
@@ -45,6 +45,8 @@ nir_shader_create(void *mem_ctx,<br>
    shader->options = options;<br>
<br>
    shader->info = si ? si : rzalloc(shader, shader_info);<br>
+   if (!si)<br>
+      shader->shader_owns_info = true;<br>
<br>
    exec_list_make_empty(&shader-><wbr>functions);<br>
    exec_list_make_empty(&shader-><wbr>registers);<br>
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h<br>
index 92647632462b..7dde8bd4ebd6 100644<br>
--- a/src/compiler/nir/nir.h<br>
+++ b/src/compiler/nir/nir.h<br>
@@ -1807,6 +1807,8 @@ typedef struct nir_shader {<br>
    /** Various bits of compile-time information about a given shader */<br>
    struct shader_info *info;<br>
<br>
+   bool shader_owns_info;<br>
+<br>
    /** list of global variables in the shader (nir_variable) */<br>
    struct exec_list globals;<br>
<br>
diff --git a/src/compiler/nir/nir_clone.c b/src/compiler/nir/nir_clone.c<br>
index 9f3bd7ff6baa..cd6063325274 100644<br>
--- a/src/compiler/nir/nir_clone.c<br>
+++ b/src/compiler/nir/nir_clone.c<br>
@@ -710,7 +710,19 @@ nir_shader_clone(void *mem_ctx, const nir_shader *s)<br>
    clone_reg_list(&state, &ns->registers, &s->registers);<br>
    ns->reg_alloc = s->reg_alloc;<br>
<br>
-   ns->info = s->info;<br>
+   if (s->shader_owns_info) {<br>
+      ns->info = ralloc(ns, struct shader_info);<br>
+      *ns->info = *s->info;<br>
+      ns->shader_owns_info = true;<br>
+   } else {<br>
+      ns->info = s->info;<br>
+   }<br>
+<br>
+   /* XXX: Note that for !shader_owns_info, we're making the info pointed to<br>
+    * by s have data owned by ns, so if ns is freed before s then we might<br>
+    * use-after-free the name/label.  We should probably have name/label be<br>
+    * owned by the info.<br>
+    */<br>
    ns->info->name = ralloc_strdup(ns, ns->info->name);<br>
    if (ns->info->label)<br>
       ns->info->label = ralloc_strdup(ns, ns->info->label);<br>
diff --git a/src/compiler/nir/nir_sweep.c b/src/compiler/nir/nir_sweep.c<br>
index faf696d6decd..43664d4d5b96 100644<br>
--- a/src/compiler/nir/nir_sweep.c<br>
+++ b/src/compiler/nir/nir_sweep.c<br>
@@ -153,6 +153,9 @@ nir_sweep(nir_shader *nir)<br>
    /* First, move ownership of all the memory to a temporary context; assume dead. */<br>
    ralloc_adopt(rubbish, nir);<br>
<br>
+   if (nir->shader_owns_info)<br>
+      ralloc_steal(nir, nir->info);<br>
+<br>
    ralloc_steal(nir, (char *)nir->info->name);<br>
    if (nir->info->label)<br>
       ralloc_steal(nir, (char *)nir->info->label);<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.10.1<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>