如何修正遗留代码中memcpy触发的Fortify缓冲区溢出告警?
解决Fortify标记的缓冲区溢出问题
问题根源分析
Fortify静态扫描只认代码逻辑里的风险点,不会采信“实际场景中长度足够”的主观判断:
sprintf无长度限制,若somefunct_string.c_str()过长,会直接撑爆temp缓冲区;memcpy未将temp长度与buf分配大小len做校验,代码逻辑上存在超出buf范围的可能;- 代码中
temp.length()是错误写法——C++的char数组没有length()成员函数,应使用strlen(temp),错误的长度计算会进一步放大溢出风险。
具体修复方案
替换
sprintf为安全的snprintf,限制写入temp的最大长度,避免temp自身溢出:char temp[256]; // 用sizeof(temp)-1限制长度,预留字符串终止符'\0'的位置 snprintf(temp, sizeof(temp)-1, "abcd%s", somefunct_string.c_str()); // 手动补终止符(部分编译器的snprintf在缓冲区满时不会自动添加,保险起见) temp[sizeof(temp)-1] = '\0';在
memcpy前添加长度校验,确保复制长度不超过buf的分配大小:size_t temp_len = strlen(temp); // 优先判断长度,再执行复制,避免越界 if (temp_len + 1 < len) { memcpy(*buf, temp, temp_len + 1); // 同步复制字符串终止符,保证buf内字符串完整 } else { // 根据业务逻辑处理溢出场景,比如截断或报错 memcpy(*buf, temp, len - 1); (*buf)[len - 1] = '\0'; }可选:改用C++字符串操作替代C风格函数,从根源规避缓冲区问题:
std::string temp_str = "abcd" + somefunct_string; if (temp_str.size() + 1 < len) { strcpy(reinterpret_cast<char*>(*buf), temp_str.c_str()); } else { strncpy(reinterpret_cast<char*>(*buf), temp_str.c_str(), len - 1); (*buf)[len - 1] = '\0'; }
内容的提问来源于stack exchange,提问作者RC0993
相关产品推荐
相关产品推荐

