我最近安装了“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 案例。

总的来说,这是一个很好的产品,但它确实有一些漏洞,你无法解决所有的抱怨。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top