diff options
author | alan-baker <alanbaker@google.com> | 2022-10-24 22:16:33 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-24 22:16:33 +0300 |
commit | 7326b967a52aecef25b3fedaaba388d6616db93d (patch) | |
tree | e57c45ccd02c202437d59ef538460b3ee49f43fe | |
parent | 0ebf830572133cc0b95e39990ae0bb0767aa52fe (diff) |
Prevent null pointer from being dereferenced (#4971)
Fixes https://crbug.com/oss-fuzz/48553
* Assign a reflexive dominator if no other dominator can be found using
forward traversals
* This prevents a null dereference of a pointer in the sorting of the
output
-rw-r--r-- | source/cfa.h | 8 | ||||
-rw-r--r-- | test/val/val_cfg_test.cpp | 27 |
2 files changed, 34 insertions, 1 deletions
diff --git a/source/cfa.h b/source/cfa.h index 2743ab40c..9ae3e39a1 100644 --- a/source/cfa.h +++ b/source/cfa.h @@ -275,10 +275,16 @@ std::vector<std::pair<BB*, BB*>> CFA<BB>::CalculateDominators( std::vector<std::pair<bb_ptr, bb_ptr>> out; for (auto idom : idoms) { + // At this point if there is no dominator for the node, just make it + // reflexive. + auto dominator = std::get<1>(idom).dominator; + if (dominator == undefined_dom) { + dominator = std::get<1>(idom).postorder_index; + } // NOTE: performing a const cast for convenient usage with // UpdateImmediateDominators out.push_back({const_cast<BB*>(std::get<0>(idom)), - const_cast<BB*>(postorder[std::get<1>(idom).dominator])}); + const_cast<BB*>(postorder[dominator])}); } // Sort by postorder index to generate a deterministic ordering of edges. diff --git a/test/val/val_cfg_test.cpp b/test/val/val_cfg_test.cpp index a4d144419..c8dd4a2fd 100644 --- a/test/val/val_cfg_test.cpp +++ b/test/val/val_cfg_test.cpp @@ -4601,6 +4601,33 @@ OpFunctionEnd "does not structurally dominate the back-edge block '8[%8]'")); } +TEST_F(ValidateCFG, BadLoop) { + const std::string text = R"( +OpCapability Shader +OpMemoryModel Logical Simple +OpEntryPoint Fragment %2 " " +OpExecutionMode %2 OriginUpperLeft +OpName %49 "loop" +%void = OpTypeVoid +%12 = OpTypeFunction %void +%2 = OpFunction %void None %12 +%33 = OpLabel +OpBranch %49 +%50 = OpLabel +OpBranch %49 +%49 = OpLabel +OpLoopMerge %33 %50 Unroll +OpBranch %49 +OpFunctionEnd +)"; + + CompileSuccessfully(text); + EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Loop header '2[%loop]' is targeted by 2 back-edge " + "blocks but the standard requires exactly one")); +} + } // namespace } // namespace val } // namespace spvtools |