题
我最近安装了“klocwork”,并试图消除现有代码上的错误。显示的错误似乎很简单。终止时不为 null char * _p_
. 。我已经手动添加了一个空终止符(即使没有必要),但它并不能让 Klocwork 满意。有任何想法吗?
确切的消息是:-
错误终止的字符串 'p' 导致缓冲区溢出 p.
char *ptr;
int writtenchars = 0 ;
va_list args;
char* destStr;
if (argc != 2) {
printf(" wrong parameters number - %d instead of %d\n", argc, 2);
char str[25]="wrong parameters number ";
char *_p_; /********************************************************/
va_start(args, str);
destStr = (char*) malloc(SNMP_BUF_LEN);
_p_= destStr;
if (destStr == NULL) {
printf("WARNING: Failed to alloc memory in in function \"snmp_rebuildstringinbuf!!!\" \n");
destStr="kukuRiko";
}
else {
writtenchars = (int) vsnprintf(destStr, 4095, str, args);
if (writtenchars>SNMP_BUF_LEN) {
printf("WARNING: Too long string rebuilded in function \"snmp_rebuildstringinbuf!!!\" %d chars\n",writtenchars);
}
destStr[writtenchars] = '\0' ; //Moshe - making sure the last value of the string is null terminated in order to prevent future buffer overflows.
}
va_end(args);
/******************************************************************************/
//The KlocWork error relates to this line //
logCWriteLog_msg(moduleId, level, __FILE__, __LINE__, _p_, ltrue);
free (_p_);
=============================================== ========嗨,大家好,谢谢您的回答,但似乎比这更晦涩。我已经将代码完善了此简单的情况: - 当代码写入一个函数时,没有错误,而当分配部分包裹在函数中(和文本作为参数传递)时,klocwork错误返回。请参阅此代码:- 没有错误的版本:-
char *_p_; /*+++++++++++++++++++*/
int writtenchars = 0 ;
va_list args;
char* destStr;
char* str = "hello World";
va_start(args, str);
destStr = (char*)malloc(SNMP_BUF_LEN);
if (destStr == NULL) {
printf("WARNING: Failed to alloc memory in function \n");
}
else {
writtenchars = (int) vsnprintf(destStr, (SNMP_BUF_LEN) - 1, str, args);
}
/*+++++++++++++++++++*/
_p_ = destStr ;
if (_p_ != NULL) {
logCWriteLog_msg(moduleId, level, __FILE__, __LINE__, _p_, ltrue);
}
free (_p_);
/***********************************************************/
而当在 /*++++ */ 之间获取代码并将其包装在函数中时,会返回上述 KlocWork 错误。
因此,
char *writingToSomeBuffer (char * str) {
int writtenchars = 0 ;
va_list args;
char* destStr;
va_start(args, str);
destStr = (char*)malloc(SNMP_BUF_LEN);
if (destStr == NULL) {
printf("WARNING: Failed to alloc memory in function \n");
}
else {
writtenchars = (int) vsnprintf(destStr, (SNMP_BUF_LEN) - 1, str, args);
}
return destStr;
}
int main () {
char *_p_;
_p_ = writingToSomeBuffer("hello world");
if (_p_ != NULL) {
logCWriteLog_msg(moduleId, level, __FILE__, __LINE__, _p_, ltrue);
}
free (_p_);
return 0 ;
}
有任何想法吗?
解决方案
乔纳森(Jonathan)做对了。最近,我们将此检查器分为两个家庭,可以更好地解释它:
http://www.klocwork.com/products/docuctation/insight-9.1/checkers:nnts.might http://www.klocwork.com/products/docuctation/insight-9.1/checkers:nnts.ust
我们目前正在开发清理并更容易理解。不仅问题,而且解决方案。
其他提示
如果内存分配失败,KLOCWORK正确地诊断出您可以用空指针编写的问题:
_p_= destStr;
if (destStr == NULL)
{
printf("WARNING: Failed to alloc memory in in function ...\n");
destStr = "kukuRiko";
在这一点上,(可怕的命名)'_p_
'变量仍然为null,但是您可以继续在下面的打印操作中使用它。
另请注意,“添加的“微不足道”修复_p_
``之后都打破了您的内存管理;你以后做'free(_p_);
“如果这将导致可怕的问题”_p_
'指向恒定字符串。
您也有“记忆” 在 函数'在消息中。 “错误的参数编号”确实意味着与“错误的参数数”大致相同,但后者更惯用英语。我不相信任何感叹号对错误消息有帮助。有一个有力的论点是,即使其中一个被认为是理想的,他们也应该超出围绕函数名称的双引号。
有了问题的修订版,我想知道Klocwork是否正在诊断Microsoft所说的 vsnprintf(), ,它不能保证终止终止(这与C99和C99和 posix 说)。
撇开 Klocwork 的错误不谈,我认为这段代码是错误的。你为什么要限制 vsnprintf
到 4096,而缓冲区大小为 SNMP_BUF_LEN
?这两者有何关系?如果 SNMP_BUF_LEN
< 4096,那么您可能刚刚溢出了缓冲区。你为什么不通过 SNMP_BUF_LEN
作为 vsnprintf 中的限制参数?
另外,写入 destStr[writtenchars]
是可疑的。根据 vsnprintf 的变体(它们确实有所不同),writingchars 可能是它的字符数 通缉 写入,这将再次导致您写入超出缓冲区末尾。
综上所述,Klocwork 并不完美。我们的宏非常明确地试图确保安全,但 Klocwork 错误地将它们检测为可能超出字符串。我认为这也是一个 snprintf 案例。
总的来说,这是一个很好的产品,但它确实有一些漏洞,你无法解决所有的抱怨。