11
votes

Comment lire des chiffres en utilisant SSCANF Crash?

CPPCheck a détecté un problème potentiel dans un code comme celui-ci:

float a, b, c;
int count = sscanf(data, "%f,%f,%f", &a, &b, &c);


9 commentaires

Essayez SSCANF_S à la place. Comme Scanf normal, SCANF n'est pas trop sûr.


@guitarflow: Le problème est que je ne vois pas où il peut trop déborder.


@guitarflow ou non. SSCANF_S n'est pas portable et non en toute sécurité, malgré ce que le nom suggère et des revendications Microsoft.


en.wikipedia.org/wiki/format_string_attack est également important de faire attention à. Les débordements de tampons seuls ne sont pas les seules vulnérabilités des analyses. Si vous autorisez l'utilisateur à saisir la chaîne de format, ils peuvent utiliser% x pour imprimer des emplacements de mémoire arbitraires et% n pour les écrire. Entre autres.


@synthesizerpatel: Comme vous pouvez le constater, le format est un littéral à chaîne ici, de sorte que ce n'est pas un problème.


Oui, dans ce cas particulier peut-être. Mais c'est le problème avec l'analyse de code statique - vous obtenez beaucoup de faux positifs. J'essaie d'éviter Scanf juste parce que quiconque hérite mon code pourrait ne pas savoir quelles sont les limites de la sécurité. Mais c'est juste moi.


@Konradrudolph vraiment? Je savais que ce n'est pas portable mais je ne savais pas le danger potentiel. Qu'est-ce qui le rend dangereux?


@Jurajblaho Vérifiez ceci out Craseux.com/books/CTULTAL/sscanf.html#sScanf


@guitarflow Eh bien il présuppose que vous connaissez déjà la taille du tampon. Mais c'est généralement le problème en premier lieu. sscanf_s ne vérifie pas (et ne peut pas vérifier) ​​si la taille du tampon est correcte. Il ne protège donc que dans la mesure où il rend la taille du tampon explicite. Une méthode beaucoup supérieure à la prévention des débordements tampons en premier lieu et C ++ fait ce trivial. (Aussi, au moins une des commandes "sûre" - mais je ne me souviens pas qui - eu un bug de débordement tampon. Oh l'ironie.)


3 Réponses :


1
votes

OK, considérez ce code:

int main(int argc, char *argv[]) {
    const char* data = "9999999999999999999999999.9999999999999999999999//i put alot more 9's there, this just to get the point through
    float a;
    int count = sscanf(data, "%f", &a);
    printf("%f",a);
}


4 commentaires

Avec quels compilateurs avez-vous vérifié cela?


compilé avec juste g ++. Pourquoi avez-vous eu un résultat différent avec un autre compilateur?


Pas encore, mais je pense que la conclusion "CPPCheck est tout à fait faux" peut être un peu prématurée lors de l'essai sur un seul compilateur. (Je ne peux que tester avec VC ++ 2005, où je suis assis maintenant, désolé.)


Avez-vous essayé l'échantillon posté par Daniel Marjamäki dans votre compilateur?



7
votes

Je suis un développeur de CPPCheck.

Oui c'est un accident étrange. Avec des "données énormes", cela signifie des millions de chiffres.

Si vous utilisez le drapeau -verbose, le CPPCheck écrira en fait un petit code d'exemple qui se bloque généralement sur des ordinateurs Linux.

ici est un exemple de code qui se bloque avec une défaillance de segmentation sur mon ordinateur Ubuntu 11.10: xxx

Pour vos informations, je ne reçois pas de crash lorsque j'essaie ce code d'exemple sur Visual Studio .

J'ai utilisé g ++ version 4.6.1 pour compiler.


3 commentaires

La question reste. Pourquoi ça se bloque? Je ne vois aucune raison lorsque le code pour analyser le numéro pourrait être quelque chose comme: pour chaque chiffre dans les données: Résultat * = 10; Résultat + = chiffre . Comment cela pourrait-il crash? Pourquoi n'est-ce pas corrigé?


Je voulais principalement répondre "est-ce un faux positif dans le CPPCheck?". C'est un crash étrange donc il est facile de le penser. Je ne peux pas répondre pourquoi techniquement il se bloque. Il a été un problème connu et répandu pendant des années. Je conviens que avec votre code, il ne peut pas griller si évidemment que ce n'est pas la manière dont les données sont analysées.


Oui je comprends. Merci au moins pour une réponse partielle. Je vous ai donné +1.



4
votes

Le défaut de segmentation semble être un bug dans glibc.

Je viens de tester cela avec un programme similaire, qui se bloque à Ubuntu 10.04, Mais travaille à Ubuntu 12.04.

Comme Daniel Marjamäki a déclaré, son programme se bloque en 11.10, je crois que le bogue est fixé entre.


0 commentaires