函数 CalcTransposeTmpSizeV2 在第27-28行通过 GetTensorVectorizedRepeats 填充 output_vectorized_repeats,随后在第30行执行 output_vectorized_repeats[output_vectorized_repeats.size() - 1]。GetTensorVectorizedRepeats 遍历 attr.vectorized_axis 进行填充,当 attr.vectorized_axis 为空时(该场景在 RemoveAllZeroStrideVectorizedAxis 优化 pass 中可能发生——若所有轴的 stride 均为零则全部移除),output_vectorized_repeats 保持为空,size() 返回 0,size()-1 发生无符号整数下溢为 SIZE_MAX,导致巨大索引越界访问。第28行的 GE_ASSERT_TRUE(GetTensorVectorizedRepeats(...)) 无效,因为该函数恒返回 true,不会因空容器而触发断言。
核查1模式成立:transpose_v2.cpp:30 执行 output_vectorized_repeats[output_vectorized_repeats.size()-1],若容器为空则 size()-1 无符号下溢为 SIZE_MAX 导致越界。 GetTensorVectorizedRepeats(15-23行)遍历 attr.vectorized_axis 填充,恒返回 true(22行 return true),故第28行 GE_ASSERT_TRUE 无效,不会因空容器触发断言。 核查2无有效防护:GE_ASSERT_TRUE(GetTensorVectorizedRepeats(...)) 因函数恒返回 true 而无效;codegen 阶段的 IsRepeatStrideValid(codegen_graph_check.cpp:207)仅检查 vectorized_axis 与 vectorized_strides 尺寸一致,不检查非空,且晚于 buffer 分配。 核查3函数可达:call_sites 确认 CalcTmpBufSize(v2_ascir_codegen_impl.h:3677)直接转发。 核查4上游有间接未确证路径:RemoveAllZeroStrideVectorizedAxis(vector_func_partitioner.cpp:250-279)在 partition 阶段(1192行调用,先于 buffer 分配)可移除所有零 stride 轴使 vectorized_axis 为空;un_alignment_strategy.cpp:430 和 asc_graph_ub_expr_builder.cpp:65 均显式处理 vectorized_axis.empty(),证实空场景在代码库中被认可。 但 Transpose 节点输出是否实际出现全零 stride 未确证。 属假设性缺陷,上游有间接未确证路径,对应 confidence 0.86
Source(问题源头) autofuse/v35/ascir/reg_func/transpose_v2.cpp:26 行 node_outputs[0].attr.vectorized_axis 可能经 RemoveAllZeroStrideVectorizedAxis 优化后为空
Source(问题源头)
autofuse/v35/ascir/reg_func/transpose_v2.cpp:26 行 node_outputs[0].attr.vectorized_axis 可能经 RemoveAllZeroStrideVectorizedAxis 优化后为空
Sink(问题爆发点) autofuse/v35/ascir/reg_func/transpose_v2.cpp:30 行 output_vectorized_repeats[output_vectorized_repeats.size() - 1] 对空容器执行 size()-1 下溢后越界访问(越界 sink)
Sink(问题爆发点)
autofuse/v35/ascir/reg_func/transpose_v2.cpp:30 行 output_vectorized_repeats[output_vectorized_repeats.size() - 1] 对空容器执行 size()-1 下溢后越界访问(越界 sink)
传播路径:
std::vector<Expression> output_vectorized_repeats; GE_ASSERT_TRUE(GetTensorVectorizedRepeats(attr, output_vectorized_repeats)); if (output_vectorized_repeats.empty()) { return {}; } Expression input_size = output_vectorized_repeats[output_vectorized_repeats.size() - 1];
你好,感谢建议, 后续分析处理
缺陷信息
缺陷描述
函数 CalcTransposeTmpSizeV2 在第27-28行通过 GetTensorVectorizedRepeats 填充 output_vectorized_repeats,随后在第30行执行 output_vectorized_repeats[output_vectorized_repeats.size() - 1]。GetTensorVectorizedRepeats 遍历 attr.vectorized_axis 进行填充,当 attr.vectorized_axis 为空时(该场景在 RemoveAllZeroStrideVectorizedAxis 优化 pass 中可能发生——若所有轴的 stride 均为零则全部移除),output_vectorized_repeats 保持为空,size() 返回 0,size()-1 发生无符号整数下溢为 SIZE_MAX,导致巨大索引越界访问。第28行的 GE_ASSERT_TRUE(GetTensorVectorizedRepeats(...)) 无效,因为该函数恒返回 true,不会因空容器而触发断言。
事实核查
数据流证据
传播路径:
修复建议
std::vector<Expression> output_vectorized_repeats; GE_ASSERT_TRUE(GetTensorVectorizedRepeats(attr, output_vectorized_repeats)); if (output_vectorized_repeats.empty()) { return {}; } Expression input_size = output_vectorized_repeats[output_vectorized_repeats.size() - 1];