已关闭
【缺陷报告】空指针解引用 - 文件expression.cc - 函数Expression::Compare - 行号181 #264
zhangjunkai9创建于  14 天前关闭于  9 天前
zhangjunkai9
14 天前 创建

缺陷信息

缺陷类型nullptrDeref (空指针解引用)
函数Expression::Compare
文件autofuse/graph_metadef/graph/expression/expression.cc
行号181
置信度86%

缺陷描述

Expression::Compare(const Expression &e) 在第181行执行 impl_->Compare(*e.impl_),仅校验了 this->impl_(第180行 if (impl_ != nullptr))未校验 e.impl_。e 为函数入参,其 impl_ 可能为空:Expression 可通过 Expression(ExpressionImplPtr &&e) 构造函数(第269行)传入空指针(如 Expression(nullptr));Expression::Parse 在 str 为 nullptr 时返回 Expression(nullptr)(第73行);Expression::Deserialize 在解析失败时返回空 impl_(expression_impl.cc:219)。此外 ComGraphMakeUnique() 使用 new(std::nothrow)(ge_util.h:57)也可能返回空。同文件 operator==(第252行)同时校验了 impl_ 和 e.impl_(if (impl_ != nullptr && e.impl_ != nullptr)),表明 Compare 遗漏了对 e.impl_ 的校验。Compare 被用于排序比较器(attr_group_shape_env.h:95 SymbolCheckInfoKeyLess、symbolic.h:314),若含空 impl_ 的 Expression 进入有序容器将触发比较并崩溃。

事实核查

经复核:(1) 模式成立——expression.cc:180 仅校验 impl_!=nullptr(this),未校验 e.impl_,第181行 impl_->Compare(*e.impl_) 解引用 e.impl_;同文件 operator==(第252行)同时校验 impl_ 和 e.impl_,证实校验必要且 Compare 遗漏。
(2) 无有效防护——对 e.impl_ 无校验。
(3) 函数可达——call_sites 确认 symbolic.h:314 ExpressionKeyLess 比较器 return x.Compare(y)==-1,attr_group_shape_env.h:95 SymbolCheckInfoKeyLess 比较器 return a.expr.Compare(b.expr)<0,均用于有序容器排序。
(4) 触发条件无法证实满足——e.impl_ 可能为空(Parse(nullptr) 返回 Expression(nullptr) 第73行、Expression(nullptr) 构造第269行、Deserialize 失败、ComGraphMakeUnique OOM),但 null-impl Expression 是否实际进入有序容器触发比较器调用未证实,比较器实参 x/y 是否含 null impl_ 模糊。
判定为假设性缺陷,调用方实参存在模糊(可能触发未证实),对应 confidence 0.86。

数据流证据

Source(问题源头)

autofuse/graph_metadef/graph/expression/expression.cc:269 行 Expression::Expression(ExpressionImplPtr &&e) : impl_(std::move(e)) 构造函数可接收空 ExpressionImplPtr(如 Expression(nullptr)),使 impl_ 为空

Sink(问题爆发点)

autofuse/graph_metadef/graph/expression/expression.cc:181 行 return impl_->Compare(*e.impl_) e.impl_ 未经空指针校验通过 *e.impl_ 解引用(空指针解引用 sink)

传播路径:

# 文件 行号 说明
1 autofuse/graph_metadef/graph/expression/expression.cc 73 if (str == nullptr) { return Expression(nullptr); } Parse 在 str 为空时返回空 impl_ 的 Expression
2 autofuse/graph_metadef/graph/expression/expression.cc 83 return Expression(ExpressionImpl::Deserialize(str)) Deserialize 在解析失败时返回空 ExpressionImplPtr(expression_impl.cc:219 return nullptr),使 Expression 的 impl_ 为空
3 autofuse/inc/graph_metadef/graph/debug/ge_util.h 57 return std::unique_ptr(new (std::nothrow) T_nc(...)) ComGraphMakeUnique 使用 new(std::nothrow),分配失败时返回空 unique_ptr
4 autofuse/graph_metadef/graph/expression/expression.cc 272 impl_ = ComGraphMakeUnique("") 默认构造使用 ComGraphMakeUnique,可能返回空
5 autofuse/graph_metadef/graph/expression/expression.cc 179 int64_t Expression::Compare(const Expression &e) const e 为函数入参,e.impl_ 可能为空
6 autofuse/graph_metadef/graph/expression/expression.cc 180 if (impl_ != nullptr) 仅校验了 this->impl_,未校验 e.impl_
7 autofuse/graph_metadef/graph/expression/expression.cc 181 return impl_->Compare(*e.impl_) e.impl_ 未经空指针校验通过 *e.impl_ 解引用(sink)
8 autofuse/graph_metadef/graph/expression/expression.cc 252 if (impl_ != nullptr && e.impl_ != nullptr) operator== 同时校验了双方 impl_,证实 e.impl_ 校验是必要的且当前 Compare 遗漏了
9 autofuse/inc/graph_metadef/graph/attribute_group/attr_group_shape_env.h 95 return a.expr.Compare(b.expr) < 0 SymbolCheckInfoKeyLess 比较器调用 Compare,用于有序容器排序
10 autofuse/inc/graph_metadef/graph/symbolizer/symbolic.h 314 return x.Compare(y) == -1 比较器调用 Compare,用于有序容器排序

修复建议

int64_t Expression::Compare(const Expression &e) const {
  if ((impl_ != nullptr) && (e.impl_ != nullptr)) {
    return impl_->Compare(*e.impl_);
  }
  return std::numeric_limits<int64_t>::max();
}
likedislike
Wwangmingming成员
14 天前 将 gcw_V3YyYBt1 设为负责人
wangmingming成员
14 天前 评论:

你好,感谢建议, 后续分析处理

likedislike
Ggaoxin成员
13 天前 关联了pull request:fix: 修复 Issue #261-#276 安全加固缺陷
CANN-robotCANN-robot成员
9 天前 关闭了 issue
CANN-robotCANN-robot成员
9 天前 添加了label:resolved