2010-07-05 7 views
0

J'ai récemment installé "klocwork" et j'essaie de me débarrasser des bogues sur un code existant. L'erreur affichée semble être simple. Non null à la fin du char * _p_. J'ai manuellement ajouté une terminaison nulle (même si ce n'est pas nécessaire), mais cela ne plaît pas au Klocwork. Des idées?Chaîne non nulle terminée - une erreur KlocWork sans raison compréhensible

Le message exact est: -

Incorrectly terminated string 'p' causes a buffer overflow in 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_); 

============================== ==================================== Salut les gars, Merci pour vos réponses, mais il semble un peu plus obscur que cela. J'ai raffiné le code à ce cas simple: - Lorsque le code est écrit tout en une fonction il n'y a pas d'erreur, alors que, lorsque la section d'allocation est enveloppée dans une fonction (et un texte passé en paramètre) l'erreur Klocwork retourne. Voir ce code: - la version sans erreur: -

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

alors que lors de la prise du code entre/* ++++ */et l'enveloppant dans une fonction retourne l'erreur ci-dessus Klocwork.

Par conséquent,

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

des idées?

Répondre

0

L'erreur de Klocwork mise à part, je pense que ce code est faux. Pourquoi limitez-vous le vsnprintf à 4096, alors que la taille du tampon est SNMP_BUF_LEN? Comment ces deux sont liés les uns aux autres? Si SNMP_BUF_LEN < 4096, alors vous avez peut-être juste débordé votre tampon. Pourquoi ne pas passer SNMP_BUF_LEN comme argument limitant dans vsnprintf?

En outre, l'écriture à destStr[writtenchars] est suspect. Selon la variante de vsnprintf (ils varient), writechars peut être le nombre de caractères que voulait écrire, ce qui vous obligerait à écrire à nouveau après la fin de votre tampon.

Cela dit, Klocwork n'est pas parfait. Nous avions des macros qui essayaient très explicitement d'être en sécurité, et Klocwork les a mal détectés comme potentiellement surcharger la chaîne. Je pense que c'était aussi un cas de snprintf.

Dans l'ensemble un bon produit, mais il a quelques trous et vous ne pouvez pas résoudre toutes ses plaintes.

+0

Je suis d'accord avec votre diagnostic que 4096 et SNMP_BUF_LEN ne sont pas corrélés de façon évidente et le code serait amélioré en utilisant le même nom (SNMP_BUF_LEN) partout. Mais Klockwork diagnostique également une erreur correcte - mais pas aussi clairement que l'on pourrait souhaiter. –

3

Klocwork est diagnostiquer correctement le problème que vous pouvez être en train d'écrire avec un pointeur NULL si une allocation mémoire échoue:

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

À ce stade, le (horriblement nommé) « _p_ » variable est toujours nulle, mais vous allez-y et utilisez-le dans l'opération d'impression ci-dessous.

Notez également que le correctif «trivial» de l'ajout de «_p_» après que cela casse votre gestion de la mémoire; vous faites plus tard 'free(_p_);' ce qui conduira à d'horribles problèmes si '_p_' pointe vers la chaîne constante.

Vous avez également 'mémoire dans dans fonction' dans le message.Et 'mauvais nombre de paramètres' signifie à peu près la même chose que 'mauvais nombre de paramètres' mais ce dernier est un anglais plus idiomatique. Je ne suis pas convaincu que les points d'exclamation sont utiles dans le message d'erreur; il y a un argument fort qu'ils devraient sortir des guillemets entourant le nom de la fonction même si l'un d'entre eux est jugé souhaitable.


Avec la version révisée du problème, je me demande si Klocwork est diagnostiquait ce que Microsoft dit de son vsnprintf(), qu'il ne garantit pas la résiliation nulle (ce qui est différent de ce que dit C99 et POSIX).

Questions connexes