已关闭
[Bug]: gs_probackup 调用密码模块时可能覆盖相邻内存 #8473
Wwwing301创建于  9月7日关闭于  9月14日
Wwwing301
9月7日 创建

测试类型

安全

测试版本

7.0.0LTS

问题描述

基于 openGauss master 提交 f8a1e2d3d0bd1cff05cb2769b509a8ac1ab0f3b1

64 位系统中,密码模块接口通过 size_t * 返回长度,需要写入 8 字节。旧格式备份读取代码却只准备了一个 4 字节的 uint 变量,再强制转换成 size_t * 传给密码模块。
密码模块按接口正常写入 8 字节时,会越过这个 4 字节变量,覆盖旁边的内存。最小测试中,紧邻变量的标记值从 feedc0de 变成了 00000000。

操作系统和硬件信息

Ubuntu 22.04.5 LTS,x86_64;uint 为 4 字节,size_t 为 8 字节。

测试环境

企业版单机

被测功能

旧格式加密备份读取代码调用密码模块解密函数和 HMAC 函数时的长度返回参数。

预置条件

操作步骤

g++ -std=gnu++17 -O0 -g -Wall -Wextra poc.cc -o poc
./poc size-t-control
./poc decrypt-uint-trigger
./poc hmac-uint-trigger

预期输出

密码模块写回长度时,只修改长度变量,不应改变相邻内存。

实际输出

RC=1 LENGTH=4096 CONTROL_OK=1
RC=1 LENGTH=4096 GUARD_BEFORE=feedc0de GUARD_AFTER=00000000
RC=1 LENGTH=4096 GUARD_BEFORE=feedc0de GUARD_AFTER=00000000

后两行分别对应解密函数和 HMAC 函数,两种情况都覆盖了相邻标记值。

日志信息

相关代码:

  • src/bin/pg_probackup/catalog.cpp:3456-3458,3565,3593,3601
  • src/bin/pg_probackup/common_cipher.h:42-72

建议把两个长度变量改为 size_t,并删除强制指针转换。

提单组织

社区用户

测试代码

#include
#include
#include
#include

using callback_type = int (*)(unsigned char *, std::size_t *);

static int conforming_provider(unsigned char *output, std::size_t *output_len)
{
if (output == nullptr || output_len == nullptr) return 0;
output[0] = 0x41;
*output_len = 4096;
return 1;
}

struct alignas(std::size_t) LegacyFrame {
std::uint32_t length;
std::uint32_t adjacent_guard;
};

static bool current_uint_cast_trigger(callback_type callback)
{
unsigned char output[1] = {0};
LegacyFrame frame{8192, 0xfeedc0deU};
const auto before = frame.adjacent_guard;
const int rc = callback(output, (std::size_t *)&frame.length);
std::printf("RC=%d LENGTH=%u GUARD_BEFORE=%08x GUARD_AFTER=%08x\n",
rc, frame.length, before, frame.adjacent_guard);
return rc == 1 && frame.length == 4096 && frame.adjacent_guard == 0;
}

static bool size_t_control(callback_type callback)
{
unsigned char output[1] = {0};
std::size_t length = 8192;
const int rc = callback(output, &length);
std::printf("RC=%d LENGTH=%zu CONTROL_OK=%d\n", rc, length,
rc == 1 && length == 4096);
return rc == 1 && length == 4096;
}

int main(int argc, char **argv)
{
if (argc != 2) return 2;
const std::string name(argv[1]);
if (name == "size-t-control") return size_t_control(conforming_provider) ? 0 : 3;
if (name == "decrypt-uint-trigger") return current_uint_cast_trigger(conforming_provider) ? 0 : 4;
if (name == "hmac-uint-trigger") return current_uint_cast_trigger(conforming_provider) ? 0 : 5;
return 2;
}

likedislike
opengauss_bot
opengauss_bot成员
9月7日 评论:

This issue requires an assignee. Since you haven't specified one, we've assigned TestManager as the default assignee for this issue.

likedislike
opengauss_botopengauss_bot成员
9月7日 将 TestManager 设为负责人
opengauss_bot
opengauss_bot成员
9月7日 评论:

Welcome To openGauss Community

Hey @Wwwing301 , thanks for your contribution to the community.

Bot Usage Manual

I'm the Bot here serving you. You can find the instructions on how to interact with me at Here . That means you can comment below every pull request or issue to trigger Bot Commands. You can self-configure the PR merge rules for this repository. For more details, please refer to Here.

Contact Guide

If you have any questions, please contact the SIG: StorageEngine, AI, CM, CloudNative, SecurityTechnology, SQLEngine ,
and any of the maintainers: @CarrotGo, @chendong76, @chenxiaobin19, @congzhou2603, @dodders, @hwworkholic, @jemappellehc, @libiao2024, @muyulinzhong, @quemingjian, @shenzheng4, @shirley_zhengx, @superlchf, @totaj, @wlff234, @wofanzheng, @ywzq1161327784 ,
and any of the committers: @Igali, @bihua111, @cailei19, @h_ray, @levy53071, @libiao2024, @lihaixiao, @mrzack, @wangfeihuo, @wuyuechuan, @xiong_xjun, @zhangfengzhi123, @zhangxubo, @zhangzq131, @zjh_hw .

likedislike
opengauss_botopengauss_bot成员
9月7日 添加了label:sig/Tools
liuzhen001liuzhen001成员
9月7日 关联了看板:openGauss 7.0.0-LTS
IIgali成员
9月8日 将 zcj112 设为负责人
IIgali成员
9月9日 移除了负责人 TestManager
chendong76chendong76成员
9月10日 将 Eurekaxun 设为负责人
chendong76chendong76成员
9月10日 移除了负责人 zcj112
徐文贵徐文贵成员
9月11日 关联了pull request:[7.0.0] 修复口令清零、SHOW 清理及加解密问题
徐文贵徐文贵成员
9月11日 关联了pull request:[master] 修复口令清零、SHOW 清理及加解密问题
徐文贵
徐文贵成员
9月12日 评论:

B023[白盒,无法端到端测试]
image.png

likedislike
徐文贵徐文贵成员
9月12日 issue状态由 待办的 改变为 待回归
wuchenlong
wuchenlong成员
9月14日 评论:

回归版本:7.0.0-B023(openGauss 7.0.0 build 68f12854,compiled at 2026-09-12 16:05:53 commit 1003 last mr 9774)
回归环境:224 三节点集群(ARM),cluster_state=Normal;代码核对 openGauss-server origin/master(已 fetch)
结论:通过(legacy 解密/HMAC 长度变量已改为 size_t,去掉 uint→size_t* 强制转换)

说明:

  1. origin/master 已含 b2a20a3c2 fix(gs_probackup): correct legacy crypto output length types:hmac_len/out_buffer_len 为 size_t,调用处改为直接传 &out_buffer_len/&hmac_len,无 (size_t*)& 强制转换。
  2. issue 内开发者已注明「B023[白盒,无法端到端测试]」;本环境同样不具备硬件密码模块,无法做加密备份端到端,以白盒核对为准。
  3. issue 所附 PoC 演示的是旧 uint 强制转换模式本身,仍会覆盖相邻 guard;产品代码已不再使用该模式。
likedislike
wuchenlongwuchenlong成员
9月14日 issue状态由 待回归 改变为 已验收
wuchenlongwuchenlong成员
9月14日 关闭了 issue
徐文贵
徐文贵成员
15 天前 评论:

8.0.0-RC1 B001
image.png

likedislike
wuchenlong
wuchenlong成员
13 天前 评论:

回归版本:8.0.0-RC1.B001((openGauss 7.0.0 build 6a41b1ba) compiled at 2026-10-10 13:02:14 commit 1002 last mr 9772;8.0.0-RC1 内部版本号仍为 7.0.0,属正常)
回归环境:224 三节点主备集群(ARM,一主两备):Primary 20.20.20.224:15600,Standby 20.20.20.226 / 20.20.20.228;cluster_state=Normal;本环境无硬件密码模块,采用白盒代码核对
结论:通过(白盒:RC1 中 hmac_len/out_buffer_len 已 size_t 化、0 处强转;PoC 显示旧模式会改写相邻 GUARD,RC1 不再改写(端到端加密备份因无密码模块不可判定))
验证方式:按构建串 commit 6a41b1ba 精确取回 RC1 源码核对类型与强转,并与修复前父提交 8cc9ae3b 对照;另编译类型语义 PoC 验证 GUARD 是否被改写

说明与证据

  1. RC1 源码 src/bin/pg_probackup/catalog.cpp(commit 6a41b1ba):
3456:    size_t hmac_len = MAX_HMAC_LEN;
3458:    size_t out_buffer_len = MAX_CRYPTO_MODULE_LEN;
3565:    ..., &out_buffer_len, NULL);                  // 加解密:直接传址
3595:    ..., &out_buffer_len, NULL);
3604:    crypto_hmac_use(..., hmac_cal_buffer, &hmac_len);   // HMAC:直接传址

全文件检索 (size_t*) / (uint*) / (unsigned int*) 无匹配,uint→size_t* 强转已删除。
common_cipher.h:60/65 原型为 size_t *result_size,与实参类型一致。

  1. 修复前后对照(同一文件同一位置):
修复前 8cc9ae3b : uint hmac_len / uint out_buffer_len;调用处 (size_t*)&hmac_len、(size_t*)&out_buffer_len(3 处强转)
RC1   6a41b1ba : size_t hmac_len / size_t out_buffer_len;调用处 &hmac_len、&out_buffer_len(0 处强转)

对应修复 commit b2a20a3c2(“fix(gs_probackup): correct legacy crypto output length types”,MR !9761/!9762,2026-09-11 合入)。

  1. 类型语义 PoC(g++ -std=gnu++17 -O0 -g -Wall -Wextra,重建 issue 的 uint+强转模式对比 RC1 模式):
OLD uint+cast : LENGTH=4096 GUARD_BEFORE=feedc0de GUARD_AFTER=00000000   ← 复现 issue 报的实际输出
RC1 size_t    : LENGTH=4096 GUARD_BEFORE=feedc0de GUARD_AFTER=feedc0de   ← 相邻内存未被改写

即:旧模式确实会越界改写相邻 4 字节(GUARD 变 0),RC1 的 size_t + 直接传址不会。

覆盖度:本轮覆盖 RC1 精确构建源码的类型/强转核对、修复前后对照、类型语义 PoC;因无硬件密码模块,端到端加密备份/解密/HMAC 实跑不可判定(issue 亦标注“白盒,无法端到端测试”),本单以白盒为最终判据。

likedislike