<html>
<head>
<base href="https://bugs.freedesktop.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - i965 renderbuffer miptree creation failure not properly handled"
href="https://bugs.freedesktop.org/show_bug.cgi?id=110601">110601</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>i965 renderbuffer miptree creation failure not properly handled
</td>
</tr>
<tr>
<th>Product</th>
<td>Mesa
</td>
</tr>
<tr>
<th>Version</th>
<td>git
</td>
</tr>
<tr>
<th>Hardware</th>
<td>All
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux (All)
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>medium
</td>
</tr>
<tr>
<th>Component</th>
<td>Drivers/DRI/i965
</td>
</tr>
<tr>
<th>Assignee</th>
<td>intel-3d-bugs@lists.freedesktop.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>anssi.hannula@bitwise.fi
</td>
</tr>
<tr>
<th>QA Contact</th>
<td>intel-3d-bugs@lists.freedesktop.org
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=144142" name="attach_144142" title="Fix for issue (1), singlesample_mt use after free">attachment 144142</a> <a href="attachment.cgi?id=144142&action=edit" title="Fix for issue (1), singlesample_mt use after free">[details]</a></span>
Fix for issue (1), singlesample_mt use after free
In src/mesa/drivers/dri/i965/intel_mipmap_tree.c
intel_update_winsys_renderbuffer_miptree() the
intel_miptree_create_for_renderbuffer() call can fail and the function is
prepared for it.
However, there are several issues with the error handling:
(1) On failure exit from intel_update_winsys_renderbuffer_miptree(), the
singlesample_mt received via parameter remains assigned to
irb->singlesample_mt. However, in both callsites (brw_context.c
intel_process_dri2_buffer() and intel_update_image_buffer()) the miptree is
released on failure. This will lead to use-after-free and undefined behavior,
including crashes.
Either singlesample_mt should be NULLed or it should not be freed by caller.
I have no idea which one would be correct, but I've attached a patch that does
the former that seems to fix the use-after-free issues.
(2) On failure exit from intel_update_winsys_renderbuffer_miptree(), irb->mt
remains NULL. However, many functions seem to assume that irb->mt is non-null:
(I) do_single_blorp_clear()
(II) brw_postdraw_set_buffers_need_resolve()
(III) update_renderbuffer_surfaces()
There are probably more, but those are the ones I saw crashes in with the test
code.
An example callpath for (I) above is:
brw_clear()
=> intel_prepare_render()
=> intel_update_renderbuffers()
=> intel_process_dri2_buffer()
=> intel_update_winsys_renderbuffer_miptree()
=> fails, irb->mt = NULL
=> brw_blorp_clear_color()
=> do_single_blorp_clear()
=> dereferences irb->mt, segfault
Attached is a hack patch that adds NULL checks to some places, but I imagine a
better way would be to somehow remove the renderbuffer altogether or something
to avoid having to add mt NULL checks everywhere...
I will open a separate issue for the failure in
intel_miptree_create_for_renderbuffer() that triggers this, but I think the
error handling should be fixed regardless of the failure reason - at least so
that there are no crashes.
I've attached the test application I used as mesa-issue-qt3d.cc. With the
patches I still don't see correct graphical output with it (I see the red line
as expected but the picture flashes rapidly), but I guess it may be expected
with the miptree creation failure - I do see correct output after making
miptree creation work.
Also included is an apitrace and glxinfo with mesa master without any patches.
This was tested on a ValleyView Gen7 (8086:0f31) with kernel 3.10.35, git
master mesa (2019-05-02). AFAICS the issues can happen with any HW/kernel as
long as intel_update_winsys_renderbuffer_miptree() manages to fail.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are the assignee for the bug.</li>
<li>You are the QA Contact for the bug.</li>
</ul>
</body>
</html>