Fix use-after-free if BindGroup is the last owner of its BindGroupLayout

Destruction of the BindGroup needs to ensure that the BindGroupLayout is
destroyed after the BindGroup. This is done by using a custom deleter which
first creates an extra reference to the BGL before deleting the BindGroup.

Bug: dawn:355
Change-Id: I819bbce13473ee4738eaa304f6dac90e0501302a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/19060
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Austin Eng
2020-04-09 21:22:12 +00:00
committed by Commit Bot service account
parent 6574f92747
commit 26b7d8f6d7
5 changed files with 36 additions and 1 deletions

View File

@@ -876,4 +876,23 @@ TEST_P(BindGroupTests, ArbitraryBindingNumbers) {
DoTest(red, black, blue, RGBA8(64, 0, 255, 0));
}
// This is a regression test for crbug.com/dawn/355 which tests that destruction of a bind group
// that holds the last reference to its bind group layout does not result in a use-after-free. In
// the bug, the destructor of BindGroupBase, when destroying member mLayout,
// Ref<BindGroupLayoutBase> assigns to Ref::mPointee, AFTER calling Release(). After the BGL is
// destroyed, the storage for |mPointee| has been freed.
TEST_P(BindGroupTests, LastReferenceToBindGroupLayout) {
wgpu::BufferDescriptor bufferDesc;
bufferDesc.size = sizeof(float);
bufferDesc.usage = wgpu::BufferUsage::Uniform;
wgpu::Buffer buffer = device.CreateBuffer(&bufferDesc);
wgpu::BindGroup bg;
{
wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Vertex, wgpu::BindingType::UniformBuffer}});
bg = utils::MakeBindGroup(device, bgl, {{0, buffer, 0, sizeof(float)}});
}
}
DAWN_INSTANTIATE_TEST(BindGroupTests, D3D12Backend(), MetalBackend(), OpenGLBackend(), VulkanBackend());