飞桨安全公告 PDSA-2023-007 深度解析:paddle.linalg.matrix_rank 除零漏洞(CVE-2023-38675)的复现、修复与防护
发布时间:2026/9/13 20:06:19 作者:尧图编辑部 阅读量:1,286
的复现、修复与防护)
飞桨安全公告 PDSA-2023-007 深度解析paddle.linalg.matrix_rank 除零漏洞CVE-2023-38675的复现、修复与防护【免费下载链接】PaddlePArallel Distributed Deep LEarning: Machine Learning Framework from Industrial Practice 『飞桨』核心框架深度学习机器学习高性能单机、分布式训练和跨平台部署项目地址: https://gitcode.com/GitHub_Trending/pa/Paddle本文围绕飞桨PaddlePaddle官方安全公告 PDSA-2023-007 展开剖析paddle.linalg.matrix_rank在空张量输入下触发除零FPE漏洞CVE-2023-38675的根因、PoC 复现过程、补丁修复方案与回归测试验证。读者读完后将理解该漏洞的触发条件与源码级成因掌握修复后版本的正确行为语义并了解飞桨 FPE 类漏洞的共同模式、安全边界认定规则以及漏洞上报渠道从而在自研算子或二次开发中避免同类缺陷。一、漏洞概览PDSA-2023-007 是飞桨官方于 2023 年披露的一则安全公告完整信息如下项目内容公告编号PDSA-2023-007CVE 编号CVE-2023-38675漏洞类型FPE浮点异常由整数除零触发受影响 APIpaddle.linalg.matrix_rank受影响版本 2.6.0修复版本飞桨 2.6.0报告者Tong Liu of ShanghaiTech University在 security/README_cn.md 的公告总表中该公告与 PDSA-2023-017paddle.amin、PDSA-2023-015paddle.lerp、PDSA-2023-014paddle.topk等一批 FPE 类公告同列全部标注受影响版本 2.6.0是飞桨 2.6.0 版本批量修复的除零/浮点异常问题的典型代表。需要特别说明的是公告中的 FPE 在 POSIX 术语中对应SIGFPE信号。虽然名称含 Floating Point但本漏洞实际由整数除法numel / (rows * cols)在除数为 0 时触发导致进程以非干净方式退出崩溃这正是其被认定为安全问题的关键——详见后文安全模型一节。二、受影响 APIpaddle.linalg.matrix_rank 的功能与参数paddle.linalg.matrix_rank用于计算矩阵的秩即大于指定阈值的奇异值个数hermitianFalse时或绝对值大于阈值的特征值个数hermitianTrue时其 Python 层实现在 python/paddle/tensor/linalg.pydef matrix_rank( x: Tensor, tol: float | Tensor | None None, hermitian: bool False, atol: float | Tensor | None None, rtol: float | Tensor | None None, name: str | None None, ) - Tensor:核心参数语义如下x输入张量形状应为[..., m, n]其中...为 0 个或多个 batch 维度若x是批量矩阵则输出具有相同的 batch 维度。数据类型支持float32、float64、complex64、complex128。tol单独使用的阈值。未指定时按tol sigma * max(m, n) * eps计算其中sigma为最大奇异值或特征值绝对值eps为x数据类型对应的机器精度批量输入时每个 batch 独立计算。atol / rtol与tol互斥的绝对/相对容差组合同时指定atol/rtol时不允许再传tol否则抛出ValueError。容差最终取max(atol, sigma_1 * rtol)sigma_1为最大奇异值。若rtol未指定默认取max(m, n) * eps若rtol未指定且atol显式大于 0则rtol取 0。hermitian是否将x视为 Hermitian 矩阵。为True时走特征值分解路径更高效函数内部不校验x是否真的为 Hermitian仅使用矩阵下三角部分计算。在动态图模式下Python 层会根据参数形式分别派发到底层算子使用tol时调用matrix_rank/matrix_rank_tol使用atol/rtol时调用matrix_rank_atol_rtol见 python/paddle/tensor/linalg.py。三、漏洞根因除零语句的源码级定位公告明确指出漏洞触发条件当由x的维度计算出的rows或cols为 0 时numel / (rows * cols)会触发除 0 异常。在 Kernel 实现中batch 数量通过如下方式计算int k std::min(rows, cols); int batches static_castint(x.numel() / (rows * cols));其中rows、cols直接取自张量形状的最后两个维度auto dim_x x.dims(); int rows static_castint(dim_x[dim_x.size() - 2]); int cols static_castint(dim_x[dim_x.size() - 1]);当输入形状最后两维任一为 0例如 PoC 中的[0, 0, 0, 0, 0]rows 0, cols 0时rows * cols 0此时x.numel() 0表达式退化为整数运算0 / 0在 C 中触发未定义行为实际表现为进程收到SIGFPE信号而崩溃。GPU 路径中还存在对rows * cols INT_MAX的约束检查cusolver 的gesvdj系列接口不支持 int64 索引但空输入的除零防护是另一独立问题。从当前仓库的 CPU Kernel 实现 paddle/phi/kernels/cpu/matrix_rank_tol_kernel.cc 可以看到修复后的代码将batches的计算严格置于x.numel() 0的早退判断之后同理GPU Kernel paddle/phi/kernels/gpu/matrix_rank_tol_kernel.cu 也采用相同顺序。这一先防护、后计算的顺序正是补丁的核心改动而修复前的版本中该除零表达式直接暴露在 kernel 主流程未对空输入做前置拦截。四、PoC 复现与逐步解析公告附带的 PoC 代码如下import paddle import numpy as np x np.random.uniform(0, 0, [0, 0, 0, 0, 0]).astype(np.float32) x paddle.to_tensor(x) paddle.linalg.matrix_rank(x)逐步解析np.random.uniform(0, 0, [0, 0, 0, 0, 0])构造一个形状为[0, 0, 0, 0, 0]、元素个数为 0 的 5 维空数组uniform区间上下界均为 0 仅用于生成空数组实际并不产生任何元素。paddle.to_tensor(x)将其转换为形状[0, 0, 0, 0, 0]、dtype 为float32的飞桨张量numel() 0。paddle.linalg.matrix_rank(x)进入matrix_rankKernel最后两维rows 0, cols 0执行batches numel / (rows * cols) 0 / 0触发整数除零进程崩溃SIGFPE。该 PoC 的精妙之处在于它不需要任何恶意构造的数值仅靠空张量 零尺寸维度即可稳定触发是典型的输入校验缺失型漏洞攻击面极低、影响面极广——任何将动态形状张量如 batch 维度为 0 的数据流、预处理后为空集的特征传入matrix_rank的用户都可能命中。五、补丁修复方案空输入早退与零填充根据公告修复合入于 PR #55644 的 commit9bb6c669206c4bcc3ce3f6daf8a55650e190c1a1并包含在飞桨 2.6.0 版本中。当前仓库源码印证了修复后的防御逻辑// paddle/phi/kernels/cpu/matrix_rank_tol_kernel.cc if (x.numel() 0) { dev_ctx.template Allocint64_t(out); if (out out-numel() ! 0) { Fullint64_t, Context(dev_ctx, out-dims(), 0, out); } return; } int k std::min(rows, cols); int batches static_castint(x.numel() / (rows * cols));修复策略可概括为三点前置防护在计算k、batches含除零表达式之前先判断x.numel() 0命中即提前返回从根上杜绝除零。语义正确空矩阵的秩在数学上定义为 0因此用Full将输出填充为 0保证结果正确而非仅不崩溃。输出张量形状保持为x.shape[:-2]即去掉最后两个矩阵维后的 batch 维度与正常路径一致。CPU/GPU 双路径覆盖同样的防护逻辑同时存在于 CPU Kernel paddle/phi/kernels/cpu/matrix_rank_tol_kernel.cc 与 GPU Kernel paddle/phi/kernels/gpu/matrix_rank_tol_kernel.cumatrix_rank、matrix_rank_tol、matrix_rank_atol_rtol三个算子路径均有对应处理确保不同参数组合下行为一致。此外Kernel 注册时输出数据类型被显式指定为INT64见 paddle/phi/kernels/cpu/matrix_rank_tol_kernel.cc 的kernel-OutputAt(0).SetDataType(phi::DataType::INT64)即matrix_rank的返回值为 int64 类型这一点在验证修复后行为时需要注意。六、修复后的回归测试验证仓库中的单元测试 test/legacy_test/test_matrix_rank_op.py 专门覆盖了含 0 尺寸维度的场景是修复有效性的直接证据静态图场景构造shape[2, 0, 6, 0]的输入运行paddle.linalg.matrix_rank断言输出形状为x.shape[:-2]即[2, 6]见 test/legacy_test/test_matrix_rank_op.py。动态图 CPU/GPU 场景分别验证(2, 0, 6, 6)、(0, 0)、(2, 3, 8, 0)CPU与(2, 3, 0, 7)GPU等形状断言输出形状与x.shape[:-2]一致且输出值全部为 0见 test/legacy_test/test_matrix_rank_op.py。这些用例覆盖了rows0、cols0、全零维等多种组合既验证了不再崩溃也验证了空输入的秩为 0 的正确语义。对于升级到 2.6.0 及以后版本的用户可直接运行该测试文件确认修复状态对于框架开发者而言这也是新增防御逻辑必须配套回归测试的规范示范。七、同类 FPE 漏洞模式与通用防护经验PDSA-2023-007 并非孤例。根据 security/README_cn.md 公告总表2023 年飞桨披露的 FPE 类型漏洞还包括PDSA-2023-006paddle.nanmedianPDSA-2023-009paddle.linalg.eigPDSA-2023-014paddle.topkPDSA-2023-015paddle.lerpPDSA-2023-017paddle.aminPDSA-2023-022paddle.argmin/paddle.argmax它们与 PDSA-2023-007 均由上海科技大学的 Tong Liu 报告受影响版本同为 2.6.0并一同在 2.6.0 中修复。从这批公告可以归纳出 FPE 类漏洞的共性根因模式缺少输入形状前置校验直接使用numel、rows、cols参与除法或比值运算未考虑 0 尺寸、空张量等退化情形退化输入未定义语义数学库函数SVD、特征值分解等对 0 维矩阵的处理依赖底层 LAPACK/cuSOLVER 行为框架层必须显式定义并拦截。对算子开发者的通用防护建议凡涉及numel / (rows * cols)一类与形状相关的除法务必在运算前校验除数是否为 0凡涉及空张量numel() 0的路径必须定义明确的输出语义如 0 填充并早退同时配套覆盖 0 尺寸维度的单元测试。八、安全模型、升级建议与漏洞报告飞桨在 SECURITY_cn.md 中明确了安全问题认定边界由于模型可执行任意计算、操作文件、网络通信等飞桨计算图执行可能造成内存耗尽、死锁等非预期行为但只有当这些行为超出所涉及操作意图时才认定为安全问题框架对非预期参数和行为的检查会抛出异常Python或返回错误状态C此类干净退出不视为安全问题若非预期参数导致内存破坏或非干净退出如本公告中的 SIGFPE 崩溃则认定为安全问题。PDSA-2023-007 正属于非干净退出情形这也是其获得 CVE-2023-38675 编号并进入安全公告的原因。升级建议所有使用paddle.linalg.matrix_rank或其他受影响 API且版本低于 2.6.0 的用户应尽快升级到包含修复的 2.6.0 及以上版本因业务约束无法立即升级的应避免向该 API 传入含 0 尺寸维度的张量并在上游对动态形状做非空校验。漏洞报告飞桨鼓励安全研究人员通过百度安全应急响应中心BSRC平台负责任地披露Responsible Disclosure安全问题提交时建议包含漏洞细节与可复现的 PoC、攻击场景及攻击者可能达成的效果、问题是否已公开、署名信息。飞桨将在发布中注明修复情况并在致谢公告中公布漏洞详情与提报人信息。九、总结PDSA-2023-007CVE-2023-38675是一例典型的输入校验缺失导致除零崩溃型框架漏洞一行未防护的numel / (rows * cols)在空张量输入下即可触发 SIGFPE 使进程崩溃。修复方案以空输入早退 0 填充语义双管齐下并通过 CPU/GPU 全路径覆盖与回归测试确保了长期有效性。该案例与 2023 年同批 FPE 公告共同提醒我们数值库算子的健壮性始于对退化输入0 尺寸、空张量的显式定义与前置防护。【免费下载链接】PaddlePArallel Distributed Deep LEarning: Machine Learning Framework from Industrial Practice 『飞桨』核心框架深度学习机器学习高性能单机、分布式训练和跨平台部署项目地址: https://gitcode.com/GitHub_Trending/pa/Paddle创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考