0

最近「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_);   

================================================== =========こんにちは皆さん、回答ありがとうございますが、それよりも少しわかりにくいようです。コードをこの単純なケースに改良しました。-コードがすべて1つの関数で記述されている場合、エラーは発生しませんが、割り当てセクションが関数(およびパラメーターとして渡されたテキスト)でラップされている場合、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 ; 
}

何か案は?

4

3 に答える 3

3

KlocWork は、メモリ割り当てが失敗した場合にヌル ポインターで書き込むことができるという問題を正しく診断しています。

_p_= destStr;
if (destStr == NULL)
{
    printf("WARNING: Failed to alloc memory in in function ...\n");
    destStr = "kukuRiko";

この時点で、(恐ろしい名前の) ' _p_' 変数はまだ null ですが、次の印刷操作で使用します。

_p_また、この後に ' ' を追加するという「簡単な」修正は、メモリ管理を壊すことに注意してください。後で ' ' を実行すると、' ' が定数文字列を指しているfree(_p_);場合に恐ろしい問題が発生します。_p_

メッセージには「関数のメモリ」もあります。また、「間違ったパラメーター数」は「間違ったパラメーター数」とほぼ同じ意味ですが、後者はより慣用的な英語です。エラー メッセージで感嘆符が役立つかどうかはわかりません。それらの 1 つが望ましいと見なされたとしても、関数名を囲む二重引用符の外に出るべきであるという強い議論があります。


問題の改訂版で、Klocwork は Microsoft がそのvsnprintf()について言っていることを診断しているのか、それはヌル終了を保証しない (C99 やPOSIXの言うこととは異なる) ことを診断しているのだろうか。

于 2010-07-05T18:24:55.797 に答える
2

ジョナサンはそれを正しく理解しています。私たちは最近、このチェッカーを 2 つのファミリーに分割しました。

http://www.klocwork.com/products/documentation/Insight-9.1/Checkers:NNTS.MIGHT http://www.klocwork.com/products/documentation/Insight-9.1/Checkers:NNTS.MUST

これを整理して分かりやすくするために現在開発中です。問題だけでなく、解決策も。

于 2010-07-06T16:00:48.683 に答える
0

Klocwork のエラーはさておき、このコードは間違っていると思います。バッファ サイズが であるのに、なぜvsnprintfを 4096 に制限しているのSNMP_BUF_LENですか? この2つはどのように関係していますか?< 4096 の場合SNMP_BUF_LEN、バッファがオーバーフローした可能性があります。SNMP_BUF_LENvsnprintf の制限引数として渡さないのはなぜですか?

また、への書き込みdestStr[writtenchars]が疑わしいです。vsnprintf のバリアント (それらは異なります) によっては、 writtenchars が書き込みたい文字数になる可能性があり、これにより再びバッファーの末尾を超えて書き込むことになります。

とはいえ、Klocwork は完璧ではありません。非常に明示的に安全にしようとしているマクロがあり、Klocwork は文字列をオーバーランしている可能性があると誤って検出しました。それもsnprintfのケースだったと思います。

全体的に良い製品ですが、いくつかの穴があり、すべての不満を修正することはできません.

于 2010-07-05T17:17:10.720 に答える