From ce4447a9f6002fe13c6d8e543ca8d0693b10a551 Mon Sep 17 00:00:00 2001 From: "tairen.piao" Date: Sat, 20 Jun 2026 16:06:36 +0900 Subject: [PATCH] Fix NchwcTransformer null deref on node with unresolved schema (#28392) --- onnxruntime/core/graph/graph_utils.cc | 6 +++++- .../test/optimizer/nchwc_optimizer_test.cc | 10 ++++++++++ .../transform/transpose_cast_matmul_fp16.onnx | Bin 0 -> 762 bytes 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 onnxruntime/test/testdata/transform/transpose_cast_matmul_fp16.onnx diff --git a/onnxruntime/core/graph/graph_utils.cc b/onnxruntime/core/graph/graph_utils.cc index f083297c16fea..6ff0152dac600 100644 --- a/onnxruntime/core/graph/graph_utils.cc +++ b/onnxruntime/core/graph/graph_utils.cc @@ -396,10 +396,14 @@ bool IsSupportedOptypeVersionAndDomain(const Node& node, bool IsSupportedOptypeVersionAndDomain(const Node& node, std::string_view op_type, gsl::span versions, std::string_view domain) { +#if !defined(ORT_MINIMAL_BUILD) + // node.Op() can be null for a node whose schema is not yet resolved. + const auto* op_schema = node.Op(); +#endif return (node.OpType() == op_type && // we don't have op schemas in the minimal build so there's no way to check the deprecated flag #if !defined(ORT_MINIMAL_BUILD) - !node.Op()->Deprecated() && + op_schema != nullptr && !op_schema->Deprecated() && #endif MatchesOpSinceVersion(node, versions) && MatchesOpSetDomain(node, domain)); } diff --git a/onnxruntime/test/optimizer/nchwc_optimizer_test.cc b/onnxruntime/test/optimizer/nchwc_optimizer_test.cc index a07f173950051..d9db43b3688d1 100644 --- a/onnxruntime/test/optimizer/nchwc_optimizer_test.cc +++ b/onnxruntime/test/optimizer/nchwc_optimizer_test.cc @@ -236,6 +236,16 @@ void NchwcOptimizerTester(const std::function& bu #ifndef DISABLE_CONTRIB_OPS +// Regression test for #28392: NchwcTransformer must not crash when a node's schema is unresolved (node.Op() == nullptr). +TEST(NchwcOptimizerTests, MatMulCastDoesNotCrashOnUnresolvedSchema) { + SessionOptions session_options; + session_options.graph_optimization_level = TransformerLevel::Level3; + session_options.session_logid = "NchwcOptimizerTests"; + InferenceSessionWrapper session{session_options, GetEnvironment()}; + ASSERT_STATUS_OK(session.Load(ORT_TSTR("testdata/transform/transpose_cast_matmul_fp16.onnx"))); + ASSERT_STATUS_OK(session.Initialize()); +} + TEST(NchwcOptimizerTests, ConvNchw) { auto test_case = [&](const std::string& activation_op_type) { auto build_test_case = [&](NchwcTestHelper& helper) { diff --git a/onnxruntime/test/testdata/transform/transpose_cast_matmul_fp16.onnx b/onnxruntime/test/testdata/transform/transpose_cast_matmul_fp16.onnx new file mode 100644 index 0000000000000000000000000000000000000000..a87f4f764d6f738688a38ff274cc2459076c5c2b GIT binary patch literal 762 zcmX|prw zM^d6zo@uf>d_KQ8W0geeum*81PD(<^l0diuHCLon@|7r|wcGsI@V5wU%BN-uV_} zpMJ9eOBd}ZaWdihD713jP#O^qx$*#yA=n@U%H!c#-ARa!55eAzUYM43Hv>B~% z;;UXrijwH!{L`s)Z8&myBdout3FS?lc(phT^ba(ky?q5<#-(Fl@=G`td7h=5dIak( zykVF0X*m3#mUhXVaC0(}Zu+naSNHcKZ@z`&*CjBq?>M|ji)N$FM!ZpLgxU9<=x$0u zzh5DcCsldU#_rRDGa6JrnH0*D?ZYd7=vEDIjQue+RdPtamlSCSP9q7EQZ1xI9RZig=@ihZPLiEuvh O@5=dzDuX8ymF5pTR4XL_ literal 0 HcmV?d00001