Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spirv-val: Validate zero product workgroup size #4828

Closed
wants to merge 3 commits into from

Conversation

sjfricke
Copy link
Contributor

closes #4801

Created a EntryPointData reduce number of hash maps with the entry_point_id as the key

@dneto0
Copy link
Collaborator

dneto0 commented Jun 24, 2022

This fails the ASAN build.

For example:

[ RUN ] DecorationTest.WorkgroupSizeKernel

==2725==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000e8f80 at pc 0x000001382022 bp 0x7ffd882c5c70 sp 0x7ffd882c5c68
READ of size 4 at 0x6020000e8f80 thread T0
#0 0x1382021 in spvtools::val::Instruction::word(unsigned long) const /tmpfs/src/github/SPIRV-Tools/build/../source/val/instruction.h:66:46
#1 0x13a3ac9 in spvtools::val::(anonymous namespace)::ValidateDecorationTarget(spvtools::val::ValidationState_t&, SpvDecoration_, spvtools::val::Instruction const*, spvtools::val::Instruction const*) /tmpfs/src/github/SPIRV-Tools/build/../source/val/validate_annotation.cpp:277:56
#2 0x139b9df in spvtools::val::(anonymous namespace)::ValidateDecorate(spvtools::val::ValidationState_t&, spvtools::val::Instruction const*) /tmpfs/src/github/SPIRV-Tools/build/../source/val/validate_annotation.cpp:423:22
#3 0x139abec in spvtools::val::AnnotationPass(spvtools::val::ValidationState_t&, spvtools::val::Instruction const*) /tmpfs/src/github/SPIRV-Tools/build/../source/val/validate_annotation.cpp:635:24
#4 0x137c8e3 in spvtools::val::(anonymous namespace)::ValidateBinaryUsingContextAndValidationState(spv_context_t const&, unsigned int const*, unsigned long, spv_diagnostic_t**, spvtools::val::ValidationState_t*) /tmpfs/src/github/SPIRV-Tools/build/../source/val/validate.cpp:324:22
#5 0x137e432 in spvValidateWithOptions /tmpfs/src/github/SPIRV-Tools/build/../source/val/validate.cpp:443:10
#6 0x856df6 in spvtest::ValidateBase::ValidateInstructions(spv_target_env) /tmpfs/src/github/SPIRV-Tools/build/../test/val/val_fixtures.h:163:10
#7 0x86ad90 in spvtools::val::(anonymous namespace)::DecorationTest_WorkgroupSizeKernel_Test::TestBody() /tmpfs/src/github/SPIRV-Tools/build/../test/val/val_annotation_test.cpp:66:3
#8 0x181f173 in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::)(), char const) /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:2605:10
#9 0x18086aa in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::)(), char const) /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:2641:14
#10 0x17e7b22 in testing::Test::Run() /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:2680:5
#11 0x17e887c in testing::TestInfo::Run() /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:2857:11
#12 0x17e911b in testing::TestSuite::Run() /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:3011:28
#13 0x17f66ee in testing::internal::UnitTestImpl::RunAllTests() /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:5722:44
#14 0x1821e13 in bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::)(), char const) /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:2605:10
#15 0x180ac1a in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::)(), char const) /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:2641:14
#16 0x17f6245 in testing::UnitTest::Run() /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:5305:10
#17 0x17c67a0 in RUN_ALL_TESTS() /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/include/gtest/gtest.h:2486:46
#18 0x17c6781 in main /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googlemock/src/gmock_main.cc:70:10
#19 0x7f49b1b12c86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86)
#20 0x77fab9 in _start (/tmpfs/src/github/SPIRV-Tools/build/test/val/test_val_abcde+0x77fab9)

0x6020000e8f80 is located 0 bytes to the right of 16-byte region [0x6020000e8f70,0x6020000e8f80)
allocated by thread T0 here:
#0 0x82798d in operator new(unsigned long) /home/brian/src/final/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:99:3
#1 0xf0a3e0 in __gnu_cxx::new_allocator::allocate(unsigned long, void const*) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ext/new_allocator.h:114:27
#2 0xf0a365 in std::allocator_traits<std::allocator >::allocate(std::allocator&, unsigned long) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/alloc_traits.h:443:20
#3 0xf0a2f1 in std::_Vector_base<unsigned int, std::allocator >::_M_allocate(unsigned long) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:343:20
#4 0xf0b932 in void std::vector<unsigned int, std::allocator >::_M_range_initialize<unsigned int const*>(unsigned int const*, unsigned int const*, std::forward_iterator_tag) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:1579:14
#5 0x172b0fe in std::vector<unsigned int, std::allocator >::vector<unsigned int const*, void>(unsigned int const*, unsigned int const*, std::allocator const&) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:654:4
#6 0x1729c47 in spvtools::val::Instruction::Instruction(spv_parsed_instruction_t const*) /tmpfs/src/github/SPIRV-Tools/build/../source/val/instruction.cpp:26:7
#7 0x1775c8a in void __gnu_cxx::new_allocatorspvtools::val::Instruction::construct<spvtools::val::Instruction, spv_parsed_instruction_t const*&>(spvtools::val::Instruction*, spv_parsed_instruction_t const*&) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ext/new_allocator.h:146:23
#8 0x1775070 in void std::allocator_traits<std::allocatorspvtools::val::Instruction >::construct<spvtools::val::Instruction, spv_parsed_instruction_t const*&>(std::allocatorspvtools::val::Instruction&, spvtools::val::Instruction*, spv_parsed_instruction_t const*&) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/alloc_traits.h:483:8
#9 0x1754d8c in void std::vector<spvtools::val::Instruction, std::allocatorspvtools::val::Instruction >::emplace_back<spv_parsed_instruction_t const*&>(spv_parsed_instruction_t const*&) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/vector.tcc:115:6
#10 0x1735aae in spvtools::val::ValidationState_t::AddOrderedInstruction(spv_parsed_instruction_t const*) /tmpfs/src/github/SPIRV-Tools/build/../source/val/validation_state.cpp:506:25
#11 0x137e899 in spvtools::val::(anonymous namespace)::ProcessInstruction(void*, spv_parsed_instruction_t const*) /tmpfs/src/github/SPIRV-Tools/build/../source/val/validate.cpp:91:25
#12 0x12f0627 in (anonymous namespace)::Parser::parseInstruction() /tmpfs/src/github/SPIRV-Tools/build/../source/binary.cpp:409:22
#13 0x12eb892 in (anonymous namespace)::Parser::parseModule() /tmpfs/src/github/SPIRV-Tools/build/../source/binary.cpp:285:22
#14 0x12e960b in (anonymous namespace)::Parser::parse(unsigned int const*, unsigned long, spv_diagnostic_t**) /tmpfs/src/github/SPIRV-Tools/build/../source/binary.cpp:243:31
#15 0x12e910c in spvBinaryParse /tmpfs/src/github/SPIRV-Tools/build/../source/binary.cpp:821:17
#16 0x137a88b in spvtools::val::(anonymous namespace)::ValidateBinaryUsingContextAndValidationState(spv_context_t const&, unsigned int const*, unsigned long, spv_diagnostic_t**, spvtools::val::ValidationState_t*) /tmpfs/src/github/SPIRV-Tools/build/../source/val/validate.cpp:206:20
#17 0x137e432 in spvValidateWithOptions /tmpfs/src/github/SPIRV-Tools/build/../source/val/validate.cpp:443:10
#18 0x856df6 in spvtest::ValidateBase::ValidateInstructions(spv_target_env) /tmpfs/src/github/SPIRV-Tools/build/../test/val/val_fixtures.h:163:10
#19 0x86ad90 in spvtools::val::(anonymous namespace)::DecorationTest_WorkgroupSizeKernel_Test::TestBody() /tmpfs/src/github/SPIRV-Tools/build/../test/val/val_annotation_test.cpp:66:3
#20 0x181f173 in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::)(), char const) /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:2605:10
#21 0x18086aa in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::)(), char const) /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:2641:14
#22 0x17e7b22 in testing::Test::Run() /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:2680:5
#23 0x17e887c in testing::TestInfo::Run() /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:2857:11
#24 0x17e911b in testing::TestSuite::Run() /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:3011:28
#25 0x17f66ee in testing::internal::UnitTestImpl::RunAllTests() /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:5722:44
#26 0x1821e13 in bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::)(), char const) /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:2605:10
#27 0x180ac1a in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::)(), char const) /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:2641:14
#28 0x17f6245 in testing::UnitTest::Run() /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/src/gtest.cc:5305:10
#29 0x17c67a0 in RUN_ALL_TESTS() /tmpfs/src/github/SPIRV-Tools/build/../external/googletest/googletest/include/gtest/gtest.h:2486:46

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmpfs/src/github/SPIRV-Tools/build/../source/val/instruction.h:66:46 in spvtools::val::Instruction::word(unsigned long) const
Shadow bytes around the buggy address:
0x0c04800151a0: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
0x0c04800151b0: fa fa fd fd fa fa 00 00 fa fa 00 fa fa fa 00 00
0x0c04800151c0: fa fa 00 fa fa fa 00 00 fa fa 00 04 fa fa 00 00
0x0c04800151d0: fa fa fd fd fa fa 00 00 fa fa fd fd fa fa 00 00
0x0c04800151e0: fa fa fd fd fa fa 00 00 fa fa fd fd fa fa 00 00
=>0x0c04800151f0:[fa]fa fd fd fa fa 00 00 fa fa 00 00 fa fa 00 00
0x0c0480015200: fa fa 00 00 fa fa 00 00 fa fa fa fa fa fa fa fa
0x0c0480015210: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0480015220: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0480015230: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0480015240: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==2725==ABORTING

  Start 29: spirv-tools-test_val_capability

Copy link
Collaborator

@dneto0 dneto0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pushing this forward, but the check has problems.

source/val/validate_annotation.cpp Outdated Show resolved Hide resolved
Copy link
Collaborator

@dneto0 dneto0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the value check should be moved to validate_builtins.cpp.

source/val/validate_annotation.cpp Outdated Show resolved Hide resolved
}
if (_.HasCapability(SpvCapabilityShader) &&
inst->GetOperandAs<SpvBuiltIn>(2) == SpvBuiltInWorkgroupSize) {
if (target->opcode() != SpvOpVariable) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this check could be greatly improved or just moved into the validate_builtins.cpp as well but for sake of not overloading this PR too much will leave for a post-PR fix

@@ -3123,16 +3123,6 @@ spv_result_t BuiltInsValidator::ValidateI32Vec4InputAtDefinition(

spv_result_t BuiltInsValidator::ValidateWorkgroupSizeAtDefinition(
const Decoration& decoration, const Instruction& inst) {
if (spvIsVulkanEnv(_.context()->target_env)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dneto0

the type of the constant is not checked. So someone could feed a bad module and still get a buffer overrund, I think.

In Vulkan we have the VUID

The variable decorated with WorkgroupSize must be declared as a three-component vector of 32-bit integer values

I tried to write a Kernel shader but I can't think of how it could use a Builtin WorkgroupSize without an ivec3 so I changed this to a global SPIR-V check

@s-perron
Copy link
Collaborator

This PR has gone stale. I will close it. Open a new PR if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Missing validation for static workgroup size dimensions nonzero product.
5 participants