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


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 .


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



回归版本: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* 强制转换)
说明:
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*)&强制转换。- issue 内开发者已注明「B023[白盒,无法端到端测试]」;本环境同样不具备硬件密码模块,无法做加密备份端到端,以白盒核对为准。
- issue 所附 PoC 演示的是旧
uint强制转换模式本身,仍会覆盖相邻 guard;产品代码已不再使用该模式。


8.0.0-RC1 B001



回归版本: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 是否被改写
说明与证据
- 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,与实参类型一致。
- 修复前后对照(同一文件同一位置):
修复前 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 合入)。
- 类型语义 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 亦标注“白盒,无法端到端测试”),本单以白盒为最终判据。


测试类型
安全
测试版本
7.0.0LTS
问题描述
基于 openGauss master 提交
f8a1e2d3d0bd1cff05cb2769b509a8ac1ab0f3b164 位系统中,密码模块接口通过
size_t *返回长度,需要写入 8 字节。旧格式备份读取代码却只准备了一个 4 字节的uint变量,再强制转换成size_t *传给密码模块。密码模块按接口正常写入 8 字节时,会越过这个 4 字节变量,覆盖旁边的内存。最小测试中,紧邻变量的标记值从
feedc0de变成了00000000。操作系统和硬件信息
Ubuntu 22.04.5 LTS,x86_64;
uint为 4 字节,size_t为 8 字节。测试环境
企业版单机
被测功能
旧格式加密备份读取代码调用密码模块解密函数和 HMAC 函数时的长度返回参数。
预置条件
操作步骤
预期输出
密码模块写回长度时,只修改长度变量,不应改变相邻内存。
实际输出
后两行分别对应解密函数和 HMAC 函数,两种情况都覆盖了相邻标记值。
日志信息
相关代码:
src/bin/pg_probackup/catalog.cpp:3456-3458,3565,3593,3601src/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;
}