d3d12: Disallow creating external image after device destruction

ExternalImageDXGIImpl holds a weak reference to the device. If the
device is destroyed before the image is created, the image will have a
dangling reference to the device which can cause a use-after-free.

This CL fixes that by adding a ValidateIsAlive() check before creating
the image similar to creating other API objects.

Bug: chromium:1352802
Change-Id: I477f15680ffd27e1ad0166835c4debb80b4be761
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/99384
Auto-Submit: Sunny Sachanandani <sunnyps@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Sunny Sachanandani 2022-08-17 03:52:59 +00:00 committed by Dawn LUCI CQ
parent 97a6c2a265
commit 1130a602ef
2 changed files with 24 additions and 0 deletions

View File

@ -536,6 +536,13 @@ ResultOrError<ResourceHeapAllocation> Device::AllocateMemory(
std::unique_ptr<ExternalImageDXGIImpl> Device::CreateExternalImageDXGIImpl(
const ExternalImageDescriptorDXGISharedHandle* descriptor) {
// ExternalImageDXGIImpl holds a weak reference to the device. If the device is destroyed before
// the image is created, the image will have a dangling reference to the device which can cause
// a use-after-free.
if (ConsumedError(ValidateIsAlive())) {
return nullptr;
}
// Use sharedHandle as a fallback until Chromium code is changed to set textureSharedHandle.
HANDLE textureSharedHandle = descriptor->textureSharedHandle;
if (!textureSharedHandle) {

View File

@ -832,6 +832,23 @@ TEST_P(D3D12SharedHandleUsageTests, InvalidateExternalImageOnDestroyDevice) {
EXPECT_EQ(wgpu::Texture::Acquire(externalImage->ProduceTexture(&externalAccessDesc)), nullptr);
}
// Verify external image cannot be created after the target device is destroyed.
TEST_P(D3D12SharedHandleUsageTests, DisallowExternalImageAfterDestroyDevice) {
DAWN_TEST_UNSUPPORTED_IF(UsesWire());
wgpu::Texture texture;
ComPtr<ID3D11Texture2D> d3d11Texture;
std::unique_ptr<dawn::native::d3d12::ExternalImageDXGI> externalImage;
DestroyDevice();
ASSERT_DEVICE_ERROR(WrapSharedHandle(&baseDawnDescriptor, &baseD3dDescriptor, &texture,
&d3d11Texture, &externalImage, /*fenceSignalValue=*/1));
EXPECT_EQ(externalImage, nullptr);
EXPECT_EQ(texture, nullptr);
}
DAWN_INSTANTIATE_TEST_P(D3D12SharedHandleValidation,
{D3D12Backend()},
{SyncMode::kKeyedMutex, SyncMode::kFence});