<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p style="margin-top:0;margin-bottom:0">Emil: Your alternative patch won't work because dri_make_current is not necessarily called with NULL after a buffer has been destroyed.</p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0">The problematic sequence is a pattern we use in QtWayland:</p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0">//create temporary context</p>
<p style="margin-top:0;margin-bottom:0">surface1 = eglCreateWindowSurface() <-- dri_drawable pointer is malloced</p>
<p style="margin-top:0;margin-bottom:0">eglMakeCurrent(surface1) <-- ctx->dPriv is set</p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0">// ... (Get some information about available GL extensions etc)</p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0">eglDestroySurface(surface1) <-- pointer is freed, ctx->dPriv is now dangling</p>
<p style="margin-top:0;margin-bottom:0">surface2 = eglCreateWindowSurface() <-- Creating a new surface. Sometimes it's address will be the same as the free'd pointer.</p>
<p style="margin-top:0;margin-bottom:0">eglMakeCurrent(surface2) <-- In dri_make_current, ctx->dPriv == driReadPriv may return true because the pointers may be equal</p>
<p style="margin-top:0;margin-bottom:0">      => The drawable info is not updated. Width and height for the drawable is not set from the wl_egl_window on the first frame.</p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0">Marek: How exactly does it crash? Are you sure firefox didn't previously access free'd memory through the dangling pointer and that it was just exposed now that the pointer is NULL?</p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0">Johan</p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Marek Olšák <maraeo@gmail.com><br>
<b>Sent:</b> Tuesday, April 24, 2018 6:08:16 AM<br>
<b>To:</b> Johan Helsing<br>
<b>Cc:</b> ML Mesa-dev; pekka.paalanen@collabora.co.uk; Daniel Stone; Charmaine Lee; Thomas Hellstrom; Michel Dänzer<br>
<b>Subject:</b> Re: [PATCH] st/dri: Fix dangling pointer to a destroyed dri_drawable</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div>FYI, the commit was causing crashes of qtcreator and firefox, so I reverted it.<br>
<br>
</div>
Marek<br>
</div>
<div class="x_gmail_extra"><br>
<div class="x_gmail_quote">On Fri, Apr 20, 2018 at 6:29 AM, Johan Klokkhammer Helsing
<span dir="ltr"><<a href="mailto:johan.helsing@qt.io" target="_blank">johan.helsing@qt.io</a>></span> wrote:<br>
<blockquote class="x_gmail_quote" style="margin:0 0 0 .8ex; border-left:1px #ccc solid; padding-left:1ex">
If an EGLSurface is created, made current and destroyed, and then a second<br>
EGLSurface is created. Then the second malloc in driCreateNewDrawable may<br>
return the same pointer address the first surface's drawable had.<br>
Consequently, when dri_make_current later tries to determine if it should<br>
update the texture_stamp it compares the surface's drawable pointer against<br>
the drawable in the last call to dri_make_current and assumes it's the same<br>
surface (which it isn't).<br>
<br>
When texture_stamp is left unset, then dri_st_framebuffer_validate thinks<br>
it has already called update_drawable_info for that drawable, leaving it<br>
unvalidated and this is when bad things starts to happen. In my case it<br>
manifested itself by the width and height of the surface being unset.<br>
<br>
This is fixed this by setting the pointer to NULL before freeing the<br>
surface.<br>
<br>
Bugzilla: <a href="https://bugs.freedesktop.org/show_bug.cgi?id=106126" rel="noreferrer" target="_blank">
https://bugs.freedesktop.org/<wbr>show_bug.cgi?id=106126</a><br>
Signed-off-by: Johan Klokkhammer Helsing <<a href="mailto:johan.helsing@qt.io">johan.helsing@qt.io</a>><br>
---<br>
 src/gallium/state_trackers/<wbr>dri/dri_drawable.c | 4 ++++<br>
 1 file changed, 4 insertions(+)<br>
<br>
diff --git a/src/gallium/state_trackers/<wbr>dri/dri_drawable.c b/src/gallium/state_trackers/<wbr>dri/dri_drawable.c<br>
index e5a7537e47..02328acd98 100644<br>
--- a/src/gallium/state_trackers/<wbr>dri/dri_drawable.c<br>
+++ b/src/gallium/state_trackers/<wbr>dri/dri_drawable.c<br>
@@ -185,6 +185,7 @@ fail:<br>
 void<br>
 dri_destroy_buffer(__<wbr>DRIdrawable * dPriv)<br>
 {<br>
+   struct dri_context *ctx = dri_context(dPriv-><wbr>driContextPriv);<br>
    struct dri_drawable *drawable = dri_drawable(dPriv);<br>
    struct dri_screen *screen = drawable->screen;<br>
    struct st_api *stapi = screen->st_api;<br>
@@ -202,6 +203,9 @@ dri_destroy_buffer(__<wbr>DRIdrawable * dPriv)<br>
    /* Notify the st manager that this drawable is no longer valid */<br>
    stapi->destroy_drawable(stapi, &drawable->base);<br>
<br>
+   if (ctx && ctx->dPriv == dPriv)<br>
+      ctx->dPriv = NULL;<br>
+<br>
    FREE(drawable);<br>
 }<br>
<span class="x_HOEnZb"><font color="#888888"> <br>
-- <br>
2.17.0<br>
<br>
</font></span></blockquote>
</div>
<br>
</div>
</div>
</body>
</html>