Pregunta

He instalado recientemente "Klocwork" y estoy tratando de deshacerse de los insectos en un código existente. El error que se muestra parece ser simple. No null en la terminación de la char * _p_. He añadido manualmente una terminación nula (aunque no es necesario), pero no es del agrado del Klocwork. Algunas ideas?

El mensaje exacto es: -

string incorrectamente terminado ' p ' provoca un desbordamiento de búfer en el 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_);   

=============================================== ============ Hola chicos, Gracias por sus respuestas, pero parece un poco más oscura que eso. He refinado el código para este caso sencillo: - Cuando el código se escribe todo en una función no hay ningún error, mientras que, cuando la sección de asignación está envuelto en una función (y un texto pasado como parámetro) el error vuelve Klocwork. Ver este código: - versión sin un error: -

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_);
 /***********************************************************/

mientras que la hora de tomar el código entre / * ++++ * / y envolviéndolo en una función devuelve el error anterior Klocwork.

Por lo tanto,

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 ; 
}

alguna idea?

¿Fue útil?

Solución

Jonathan tiene razón. Hemos roto recientemente este corrector en dos familias que podrían explicarlo mejor:

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

Actualmente estamos en fase de desarrollo a limpiar esto y hacer que sea más fácil de entender. No sólo el problema, pero la solución también.

Otros consejos

Klocwork es diagnosticar correctamente el problema que puede estar escribiendo con un puntero nulo si falla la reserva de memoria:

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

En este punto, el (horrible llamado) '_p_' variable sigue siendo nula, pero seguir adelante y usarlo en la operación de impresión a continuación.

Tenga en cuenta también que el arreglo 'trivial' de añadir '_p_' después de esto rompe su gestión de memoria; después No 'free(_p_);' que dará lugar a problemas horribles si _p_ '' apunta a la cadena constante.

También tiene 'memoria en Función' en el mensaje. Y 'número de parámetros erróneos' Qué significa más o menos lo mismo que 'el número de parámetros falsos', pero este último es más idiomático Inglés. No estoy convencido de cualquiera de los signos de admiración son útiles en el mensaje de error; hay un fuerte argumento de que deben ir fuera de las comillas dobles que rodean el nombre de la función, incluso si uno de ellos se considera deseable.


Con la versión revisada del problema, me pregunto si Klocwork está diagnosticando lo que Microsoft dice de su vsnprintf () , que no garantiza la terminación nula (que es diferente de lo C99 y POSIX dice ).

El error de Klocwork a un lado, creo que este código es incorrecto. ¿Por qué está limitando la vsnprintf a 4096, mientras que el tamaño del búfer es SNMP_BUF_LEN? ¿De qué manera los dos relacionados entre sí? Si SNMP_BUF_LEN <4,096, entonces es posible que acaba desbordó el búfer. ¿Por qué no pasar SNMP_BUF_LEN como argumento limitante en vsnprintf?

Además, la escritura a destStr[writtenchars] es sospechoso. Dependiendo de la variante de vsnprintf (que varían), writtenchars podría ser el número de caracteres que querido para escribir, lo que haría de nuevo causa que escribir más allá del final de la memoria intermedia.

Dicho todo esto, Klocwork no es perfecto. Tuvimos macros que estaban tratando de manera muy explícita para ser seguro, y mis-Klocwork detectamos como potencialmente invadiendo la cadena. Creo que era un caso snprintf también.

En general, un producto bueno, pero tiene un par de agujeros y no se puede arreglar todo lo que de quejas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top