Page 126 - 《软件学报》2026年第7期
P. 126
徐美秋 等: CAnalyzer: 面向 C/C++源代码的软件成分分析技术 2811
成分, 为开发者理解和分析软件组成提供了可靠的支持.
(3) 精准而完整的 TPL 依赖关系建模. CAnalyzer 通过分析源码文件中“#include”“extern”等指令以及标识符建
立 TPL 间的依赖关系图. 该依赖关系图详细展示了软件项目中各个组件之间的依赖关系, 为安全漏洞传播和软件
许可证合规性分析提供数据支持.
(4) OpenHarmony 社区认可的软件成分分析技术. CAnalyzer 已协助 OpenHarmony 社区中 689 个 C/C++代码
仓库识别出 166 个外部 C/C++ TPL 成分, 其中 61 个获得开发者确认, 为首次标注. 结合 C/C++漏洞数据库,
CAnalyzer 检测出 10 个同源安全漏洞, 其中 3 个已被社区安全响应工作组确认, 为有效漏洞. 因为本文提出的软件
成分分析技术对 OpenHarmony 社区安全治理方面的贡献, 作者团队被 OpenHarmony 安全委员会授予“OpenHarmony
社区安全治理示范单位”. CAnalyzer 开源仓库地址: https://gitcode.com/openharmony-sig/compliance_composition_
analysis.
2 背景与动机
2.1 公共函数干扰
本文所指的公共函数是指 TPL 间复用引入的克隆函数, 以及实现常见算法 (如排序算法) 等的相似函数. 这些
函数模糊了 TPL 的边界, 影响现有 SCA 技术的有效性 [13] . 图 1 展示了公共函数导致假阳性的一个典型场景: 目标
代码 third_party_selinux 复用了 selinux 库, 而后者又包含 libsepol 库的代码. 由于特征库记录了多个复用 libsepol
的 TPL, 这些 TPL 共享部分相同的函数, 导致在成分分析过程中, 所有复用 libsepol 的 TPL 都与目标代码匹配, 错
误地被识别为目标代码的一部分, 从而产生假阳性.
目标代码 特征库
特征匹配成功: 假阳性
特征匹配成功: 假阳性
特征匹配成功: 正确
图 1 公共函数造成假阳性示例
为此, 已有研究引入了函数诞生时间 [13,14] , 公共函数被归属于函数诞生时间更早的库, 然而, 在融合多个托管
仓库构建的特征库中, 函数诞生时间的准确性受到挑战.
(1) 版本管理方式的多样性使函数诞生时间难以获取. 尽管 Git 版本控制系统可提供精确的提交时间戳, 便于
追踪函数的创建时间, 但调查结果显示, 约 38.6% 的 C/C++ TPL 未采用 Git 管理 (见表 1), 而是使用其他版本控制
平台. 例如, libaiff [20] 库托管于 SourceForge [21] , 其版本控制信息的获取远不如 Git 便捷; C/C++ TPL termcap [22] 通过
FTP 服务器 (ftp://ftp.gnu.org/gnu/termcap) 发布不同版本的源代码, 缺乏标准的时间戳信息支持, 进一步加剧了函
数诞生时间的提取难度.
(2) 版本管理不完善导致获取不准确的函数诞生时间. 已有研究将软件版本的发布时间视为函数的诞生时间.
然而, 从多个托管仓库收集的 33 100 个采用 Git 版本管理的 C/C++ TPL 中 (见表 2), 20.0% 的 TPL 未标记任何
Release 或 Tag, 导致函数诞生时间难以准确确定. 对此, 已有研究者采用主分支 (master) 的最新提交时间作为近似
代替, 但这一方法存在明显的局限性 [15] . 如图 2 所示, SwiftShader 库 [23] 从未发布 Release 和 Tag. 当特征库同时包
含了最新版本的 SwiftShader2 和其他 TPL A (复用早期版本的 SwiftShader1) 时, 函数诞生时间的误判会导致函数
归属错误: 部分应属于 SwiftShade2 的函数被误认为 TPL A 的一部分, 导致目标代码在与 TPL A 的比较中产生假
阳性; 同时, 这些函数被错误剔除, 可能导致目标代码无法匹配 SwiftShader2, 从而产生假阴性.

