Commit a4c639c4 by Kimmo Kinnunen Committed by Commit Bot

D3D: Add a wrapper to Image11 that enables ASAN/MSAN to catch the errors on map operations

The wrapper should be a no-op on builds with assertions disabled. The wrapper should be useful on ASAN and MSAN builds. gn args out/release-asan --args="is_debug=false is_asan=true" ninja -C out/release-asan angle_end2end_tests ^ out\release-asan\angle_end2end_tests ^ --gtest_filter=Texture2DArrayCopy.SnormFormats* --gtest_catch_exceptions=0 ^ --gtest_repeat=-1 Output when the fix payload of angleproject:2865 is removed: ... Repeating all tests (iteration 1) . . . Note: Google Test filter = Texture2DArrayCopy.SnormFormats* [==========] Running 1 test from 1 test suite. [----------] Global test environment set-up. [----------] 1 test from Texture2DArrayCopy [ RUN ] Texture2DArrayCopy.SnormFormats/ES3_D3D11 ================================================================= ==500==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x12b2c4777040 at pc 0x7fff9602216b bp 0x00c0eaafd090 sp 0x00c0eaafd0d8 READ of size 1 at 0x12b2c4777040 thread T0 #0 0x7fff9602216a in angle::R8G8B8A8::readColor c:\Users\kkinnunen\angle\src\image_util\imageformats.cpp:333 #1 0x7fff9618dbf0 in rx::CopyImageCHROMIUM c:\Users\kkinnunen\angle\src\libANGLE\renderer\renderer_utils.cpp:377 #2 0x7fff96186bb2 in rx::Image11::CopyImage c:\Users\kkinnunen\angle\src\libANGLE\renderer\d3d\d3d11\Image11.cpp:113 #3 0x7fff95e90410 in rx::Renderer11::copyImage c:\Users\kkinnunen\angle\src\libANGLE\renderer\d3d\d3d11\Renderer11.cpp:3009 #4 0x7fff9617b447 in rx::TextureD3D_2DArray::copyTexture c:\Users\kkinnunen\angle\src\libANGLE\renderer\d3d\TextureD3D.cpp:3293 #5 0x7fff95afd7e1 in gl::Texture::copyTexture c:\Users\kkinnunen\angle\src\libANGLE\Texture.cpp:1196 #6 0x7fff95977f19 in gl::Context::copyTexture3D c:\Users\kkinnunen\angle\src\libANGLE\Context.cpp:4347 #7 0x7fff9568b04a in gl::CopyTexture3DANGLE c:\Users\kkinnunen\angle\src\libGLESv2\entry_points_gles_ext_autogen.cpp:57 #8 0x7ff7d1d8fc97 in angle::CopyTexture3DTest::testCopy c:\Users\kkinnunen\angle\src\tests\gl_tests\CopyTexture3DTest.cpp:90 #9 0x7ff7d1dadd10 in angle::Texture2DArrayCopy_SnormFormats_Test::TestBody c:\Users\kkinnunen\angle\src\tests\gl_tests\CopyTexture3DTest.cpp:1272 #10 0x7ff7d2c22891 in testing::Test::Run c:\Users\kkinnunen\angle\third_party\googletest\src\googletest\src\gtest.cc:2522 #11 0x7ff7d2c243c0 in testing::TestInfo::Run c:\Users\kkinnunen\angle\third_party\googletest\src\googletest\src\gtest.cc:2698 #12 0x7ff7d2c253e8 in testing::TestSuite::Run c:\Users\kkinnunen\angle\third_party\googletest\src\googletest\src\gtest.cc:2828 #13 0x7ff7d2c3f33e in testing::internal::UnitTestImpl::RunAllTests c:\Users\kkinnunen\angle\third_party\googletest\src\googletest\src\gtest.cc:5285 #14 0x7ff7d2c3e72d in testing::UnitTest::Run c:\Users\kkinnunen\angle\third_party\googletest\src\googletest\src\gtest.cc:4873 #15 0x7ff7d2bf10a2 in main c:\Users\kkinnunen\angle\src\tests\angle_end2end_tests_main.cpp:15 #16 0x7ff7d2d27897 in __scrt_common_main_seh f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:283 #17 0x7ff801ec7973 in BaseThreadInitThunk+0x13 (C:\WINDOWS\System32\KERNEL32.DLL+0x180017973) #18 0x7ff804cea270 in RtlUserThreadStart+0x20 (C:\WINDOWS\SYSTEM32\ntdll.dll+0x18006a270) 0x12b2c4777040 is located 0 bytes to the right of 256-byte region [0x12b2c4776f40,0x12b2c4777040) allocated by thread T0 here: #0 0x7ff7d2c6d574 in malloc C:\b\s\w\ir\k\src\third_party\llvm\projects\compiler-rt\lib\asan\asan_malloc_win.cc:68 #1 0x7fff95af47b2 in angle::MemoryBuffer::resize c:\Users\kkinnunen\angle\src\common\MemoryBuffer.cpp:40 #2 0x7fff9648c9a6 in rx::MappedSubresourceVerifier11::wrap c:\Users\kkinnunen\angle\src\libANGLE\renderer\d3d\d3d11\MappedSubresourceVerifier11.cpp:51 #3 0x7fff961864b5 in rx::Image11::map c:\Users\kkinnunen\angle\src\libANGLE\renderer\d3d\d3d11\Image11.cpp:648 #4 0x7fff9618676c in rx::Image11::CopyImage c:\Users\kkinnunen\angle\src\libANGLE\renderer\d3d\d3d11\Image11.cpp:93 #5 0x7fff95e90410 in rx::Renderer11::copyImage c:\Users\kkinnunen\angle\src\libANGLE\renderer\d3d\d3d11\Renderer11.cpp:3009 #6 0x7fff9617b447 in rx::TextureD3D_2DArray::copyTexture c:\Users\kkinnunen\angle\src\libANGLE\renderer\d3d\TextureD3D.cpp:3293 #7 0x7fff95afd7e1 in gl::Texture::copyTexture c:\Users\kkinnunen\angle\src\libANGLE\Texture.cpp:1196 #8 0x7fff95977f19 in gl::Context::copyTexture3D c:\Users\kkinnunen\angle\src\libANGLE\Context.cpp:4347 #9 0x7fff9568b04a in gl::CopyTexture3DANGLE c:\Users\kkinnunen\angle\src\libGLESv2\entry_points_gles_ext_autogen.cpp:57 #10 0x7ff7d1d8fc97 in angle::CopyTexture3DTest::testCopy c:\Users\kkinnunen\angle\src\tests\gl_tests\CopyTexture3DTest.cpp:90 #11 0x7ff7d1dadd10 in angle::Texture2DArrayCopy_SnormFormats_Test::TestBody c:\Users\kkinnunen\angle\src\tests\gl_tests\CopyTexture3DTest.cpp:1272 #12 0x7ff7d2c22891 in testing::Test::Run c:\Users\kkinnunen\angle\third_party\googletest\src\googletest\src\gtest.cc:2522 #13 0x7ff7d2c243c0 in testing::TestInfo::Run c:\Users\kkinnunen\angle\third_party\googletest\src\googletest\src\gtest.cc:2698 #14 0x7ff7d2c253e8 in testing::TestSuite::Run c:\Users\kkinnunen\angle\third_party\googletest\src\googletest\src\gtest.cc:2828 #15 0x7ff7d2c3f33e in testing::internal::UnitTestImpl::RunAllTests c:\Users\kkinnunen\angle\third_party\googletest\src\googletest\src\gtest.cc:5285 #16 0x7ff7d2c3e72d in testing::UnitTest::Run c:\Users\kkinnunen\angle\third_party\googletest\src\googletest\src\gtest.cc:4873 #17 0x7ff7d2bf10a2 in main c:\Users\kkinnunen\angle\src\tests\angle_end2end_tests_main.cpp:15 #18 0x7ff7d2d27897 in __scrt_common_main_seh f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:283 #19 0x7ff801ec7973 in BaseThreadInitThunk+0x13 (C:\WINDOWS\System32\KERNEL32.DLL+0x180017973) #20 0x7ff804cea270 in RtlUserThreadStart+0x20 (C:\WINDOWS\SYSTEM32\ntdll.dll+0x18006a270) Bug: angleproject:2865 Change-Id: I6c8fc203d075014ba8ce31c728982eed73812d04 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1640212 Commit-Queue: Kimmo Kinnunen FI <kkinnunen@nvidia.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 2d223552
...@@ -520,6 +520,7 @@ angle::Result Image11::getStagingTexture(const gl::Context *context, ...@@ -520,6 +520,7 @@ angle::Result Image11::getStagingTexture(const gl::Context *context,
void Image11::releaseStagingTexture() void Image11::releaseStagingTexture()
{ {
mStagingTexture.reset(); mStagingTexture.reset();
mStagingTextureSubresourceVerifier.reset();
} }
angle::Result Image11::createStagingTexture(const gl::Context *context) angle::Result Image11::createStagingTexture(const gl::Context *context)
...@@ -577,6 +578,7 @@ angle::Result Image11::createStagingTexture(const gl::Context *context) ...@@ -577,6 +578,7 @@ angle::Result Image11::createStagingTexture(const gl::Context *context)
mStagingTexture.setDebugName("Image11::StagingTexture3D"); mStagingTexture.setDebugName("Image11::StagingTexture3D");
mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
mStagingTextureSubresourceVerifier.setDesc(desc);
} }
break; break;
...@@ -615,6 +617,7 @@ angle::Result Image11::createStagingTexture(const gl::Context *context) ...@@ -615,6 +617,7 @@ angle::Result Image11::createStagingTexture(const gl::Context *context)
mStagingTexture.setDebugName("Image11::StagingTexture2D"); mStagingTexture.setDebugName("Image11::StagingTexture2D");
mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
mStagingTextureSubresourceVerifier.setDesc(desc);
} }
break; break;
...@@ -642,6 +645,17 @@ angle::Result Image11::map(const gl::Context *context, ...@@ -642,6 +645,17 @@ angle::Result Image11::map(const gl::Context *context,
ANGLE_TRY( ANGLE_TRY(
mRenderer->mapResource(context, stagingTexture->get(), subresourceIndex, mapType, 0, map)); mRenderer->mapResource(context, stagingTexture->get(), subresourceIndex, mapType, 0, map));
if (!mStagingTextureSubresourceVerifier.wrap(mapType, map))
{
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
deviceContext->Unmap(mStagingTexture.get(), mStagingSubresource);
Context11 *context11 = GetImplAs<Context11>(context);
context11->handleError(GL_OUT_OF_MEMORY,
"Failed to allocate staging texture mapping verifier buffer.",
__FILE__, ANGLE_FUNCTION, __LINE__);
return angle::Result::Stop;
}
mDirty = true; mDirty = true;
return angle::Result::Continue; return angle::Result::Continue;
...@@ -651,6 +665,7 @@ void Image11::unmap() ...@@ -651,6 +665,7 @@ void Image11::unmap()
{ {
if (mStagingTexture.valid()) if (mStagingTexture.valid())
{ {
mStagingTextureSubresourceVerifier.unwrap();
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
deviceContext->Unmap(mStagingTexture.get(), mStagingSubresource); deviceContext->Unmap(mStagingTexture.get(), mStagingSubresource);
} }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/ImageIndex.h" #include "libANGLE/ImageIndex.h"
#include "libANGLE/renderer/d3d/ImageD3D.h" #include "libANGLE/renderer/d3d/ImageD3D.h"
#include "libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
namespace gl namespace gl
...@@ -113,6 +114,7 @@ class Image11 : public ImageD3D ...@@ -113,6 +114,7 @@ class Image11 : public ImageD3D
DXGI_FORMAT mDXGIFormat; DXGI_FORMAT mDXGIFormat;
TextureHelper11 mStagingTexture; TextureHelper11 mStagingTexture;
unsigned int mStagingSubresource; unsigned int mStagingSubresource;
MappedSubresourceVerifier11 mStagingTextureSubresourceVerifier;
bool mRecoverFromStorage; bool mRecoverFromStorage;
TextureStorage11 *mAssociatedStorage; TextureStorage11 *mAssociatedStorage;
......
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// MappedSubresourceVerifier11.cpp: Implements the
// rx::MappedSubresourceVerifier11 class, a simple wrapper to D3D11 Texture2D
// mapped memory so that ASAN and MSAN can catch memory errors done with a
// pointer to the mapped texture memory.
#include "libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
namespace rx
{
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || defined(ANGLE_ENABLE_ASSERTS)
namespace
{
# if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER)
constexpr bool kUseWrap = true;
# else
constexpr bool kUseWrap = false;
# endif
size_t getPitchCount(const D3D11_TEXTURE2D_DESC &desc)
{
const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(desc.Format);
ASSERT(desc.Height % dxgiFormatInfo.blockHeight == 0);
return desc.Height / dxgiFormatInfo.blockHeight;
}
} // namespace
MappedSubresourceVerifier11::MappedSubresourceVerifier11() = default;
MappedSubresourceVerifier11::~MappedSubresourceVerifier11()
{
ASSERT(!mOrigData);
ASSERT(!mWrapData.size());
}
void MappedSubresourceVerifier11::setDesc(const D3D11_TEXTURE2D_DESC &desc)
{
ASSERT(desc.CPUAccessFlags & (D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE));
ASSERT(desc.Width);
ASSERT(desc.Height);
ASSERT(!mOrigData);
ASSERT(!mWrapData.size());
ASSERT(!mPitchType);
ASSERT(!mPitchCount);
mPitchType = &D3D11_MAPPED_SUBRESOURCE::RowPitch;
mPitchCount = getPitchCount(desc);
}
void MappedSubresourceVerifier11::setDesc(const D3D11_TEXTURE3D_DESC &desc)
{
ASSERT(desc.CPUAccessFlags & (D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE));
ASSERT(desc.Width);
ASSERT(desc.Height);
ASSERT(desc.Depth);
ASSERT(!mOrigData);
ASSERT(!mWrapData.size());
ASSERT(!mPitchType);
ASSERT(!mPitchCount);
mPitchType = &D3D11_MAPPED_SUBRESOURCE::DepthPitch;
mPitchCount = desc.Depth;
}
void MappedSubresourceVerifier11::reset()
{
ASSERT(!mOrigData);
ASSERT(!mWrapData.size());
mPitchType = nullptr;
mPitchCount = 0;
}
bool MappedSubresourceVerifier11::wrap(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
{
ASSERT(map && map->pData);
ASSERT(mapType == D3D11_MAP_READ || mapType == D3D11_MAP_WRITE ||
mapType == D3D11_MAP_READ_WRITE);
ASSERT(mPitchCount);
if (kUseWrap)
{
if (!mWrapData.resize(mPitchCount * map->*mPitchType))
return false;
}
mOrigData = reinterpret_cast<uint8_t *>(map->pData);
if (kUseWrap)
{
std::copy(mOrigData, mOrigData + mWrapData.size(), mWrapData.data());
map->pData = mWrapData.data();
}
return true;
}
void MappedSubresourceVerifier11::unwrap()
{
ASSERT(mPitchCount);
ASSERT(mOrigData);
if (kUseWrap)
{
std::copy(mWrapData.data(), mWrapData.data() + mWrapData.size(), mOrigData);
mWrapData = angle::MemoryBuffer();
}
mOrigData = nullptr;
}
#endif
} // namespace rx
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// MappedSubresourceVerifier11.h: Defines the rx::MappedSubresourceVerifier11
// class, a simple wrapper to D3D11 Texture2D mapped memory so that ASAN
// MSAN can catch memory errors done with a pointer to the mapped texture
// memory.
#ifndef LIBANGLE_RENDERER_D3D_D3D11_MAPPED_SUBRESOURCE_VERIFIER11_H_
#define LIBANGLE_RENDERER_D3D_D3D11_MAPPED_SUBRESOURCE_VERIFIER11_H_
#include "common/MemoryBuffer.h"
#include "common/angleutils.h"
namespace rx
{
class MappedSubresourceVerifier11 final : angle::NonCopyable
{
public:
MappedSubresourceVerifier11();
~MappedSubresourceVerifier11();
void setDesc(const D3D11_TEXTURE2D_DESC &desc);
void setDesc(const D3D11_TEXTURE3D_DESC &desc);
void reset();
bool wrap(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map);
void unwrap();
private:
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || defined(ANGLE_ENABLE_ASSERTS)
UINT D3D11_MAPPED_SUBRESOURCE::*mPitchType = nullptr;
size_t mPitchCount = 0;
angle::MemoryBuffer mWrapData;
uint8_t *mOrigData = nullptr;
#endif
};
#if !(defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || defined(ANGLE_ENABLE_ASSERTS))
inline MappedSubresourceVerifier11::MappedSubresourceVerifier11() = default;
inline MappedSubresourceVerifier11::~MappedSubresourceVerifier11() = default;
inline void MappedSubresourceVerifier11::setDesc(const D3D11_TEXTURE2D_DESC &desc) {}
inline void MappedSubresourceVerifier11::setDesc(const D3D11_TEXTURE3D_DESC &desc) {}
inline void MappedSubresourceVerifier11::reset() {}
inline bool MappedSubresourceVerifier11::wrap(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
{
return true;
}
inline void MappedSubresourceVerifier11::unwrap() {}
#endif
} // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D11_MAPPED_SUBRESOURCE_VERIFIER11_H_
...@@ -492,6 +492,8 @@ libangle_d3d11_sources = [ ...@@ -492,6 +492,8 @@ libangle_d3d11_sources = [
"src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp", "src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp",
"src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h", "src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h",
"src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h", "src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h",
"src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.cpp",
"src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h",
"src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp", "src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp",
"src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h", "src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h",
"src/libANGLE/renderer/d3d/d3d11/Program11.cpp", "src/libANGLE/renderer/d3d/d3d11/Program11.cpp",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment