2008-10-03 7 views
16

On m'a demandé de maintenir une grande base de code C++ pleine de fuites de mémoire. Tout en fouinant, j'ai découvert que nous avons beaucoup de débordements de tampon qui mènent aux fuites (comment ça a mal tourné, je ne veux jamais savoir).Quelles fonctions C/C++ sont le plus souvent utilisées de manière incorrecte et peuvent conduire à des dépassements de tampon?

J'ai décidé de supprimer les débordements de tampon en commençant par les fonctions dangereuses. Quelles fonctions C/C++ sont le plus souvent utilisées de manière incorrecte et peuvent conduire à un dépassement de tampon?

Pour compilateur et/ou les outils utilisés pour aider à rechercher dépassement de mémoire tampon, j'ai created another question that deals with this

+0

Je n'ai pas le sens de cette question. Aucune des fonctions ici ne provoque de débordement s'il est manipulé avec précaution. – unexist

+2

@unexist: Aucune fonction ne va jamais mal si elle est utilisée correctement. La question est de savoir quelles sont les fonctions les plus souvent utilisées de manière incorrecte et conduire peut donc conduire à des dépassements de tampon. –

+0

Quel compilateur/plate-forme utilisez-vous? Il y a beaucoup d'outils pour trouver ce genre de chose automatiquement. – twk

Répondre

2

Voici quelques fonctions que je trouve qui sont dangereux:

  • obtient() - Il ne vérifie la longueur de la variable et peut écraser la mémoire si l'entrée est plus grande que le tampon de la variable. Scan12() - Je suis tellement heureux que Visual Studio m'a dit que cette fonction est obsolète. C'était une solution facile. Strcpy() - Si l'espace mémoire de la source est plus grand que celui de la destination, les données après la destination sont remplacées.
2

Le lien suivant devrait vous donner un aperçu complet des fonctions de sécurité en C++ (celles qui sont postdéterminés avec « _s » pour résoudre les problèmes comme déversoirs): http://msdn.microsoft.com/en-us/library/8ef0s5kh(VS.80).aspx

EDIT: Ce lien contient les fonctions spécifiques qui ont été remplacées: http://msdn.microsoft.com/en-us/library/wd3wzwts(VS.80).aspx

EDIT: Je dois mentionner ce sont des méthodes Microsoft, mais le lien est toujours utile pour identifier les fonctions qui ont été considérées comme un drapeau rouge.

+0

Il s'agit toutefois de fonctions spécifiques à Windows, non portables. –

+0

Oui, mais ils identifient les fonctions qui posent problème. –

2

Malheureusement tout tableau peut entraîner un dépassement de mémoire tampon:

uint32_t foo[3]; 
foo[3] = WALKED_OFF_END_OF_ARRAY; 

En termes de fonctions, sprintf se fera un plaisir de marcher à l'extrémité du tampon. Il peut être remplacé par snprintf.

11

En général, toute fonction qui ne vérifie pas les limites dans les arguments. Une liste serait

  • obtient()
  • scanf()
  • strcpy()
  • strcat()

Vous devez utiliser la taille des versions limitées comme stncpy, strncat, fgets, etc. Faites alors attention en donnant la taille limite; prendre en compte le '\ 0' terminant la chaîne.

De même, les tableaux ne sont PAS liés en C ou C++. L'exemple suivant provoquerait des erreurs.Voir off by one error

int foo[3]; 
foo[3] = WALKED_OFF_END_OF_ARRAY; 

modifier: réponses Copié de @MrValdez, @Denton Gentry

+1

Je ne suis pas d'accord: les fonctions qui vérifient les limites dans les arguments sont toujours dangereuses. Si vous pouvez surcharger avec strcpy, vous pouvez surcharger avec strncpy en obtenant la borne erronée, (par exemple incrémenter le pointeur et oublier de décrémenter la borne). Pour vous protéger, utilisez std :: string ou équivalent C string lib. –

+0

Un récapitulatif plus court pourrait être "les débordements de risque des fonctions C. Les fonctions C++ ne le sont généralement pas" – Aaron

+5

Lors de l'utilisation des versions strnxxx, sachez qu'elles peuvent produire une chaîne qui n'est pas terminée par zéro – Arkadiy

0

En gros, tout ce qui accepte un pointeur et écrit, sans vérifier la longueur. Donc, chose comme strcpy(), sprintf() etc

2

Memcpy() est un autre dangereux.

Toute boucle accédant à un tableau est un point dangereux, car il n'y a pas d'arrêt au-delà de la fin du tableau.

Les fuites de mémoire sont provoquées par l'allocation de mémoire et ne libèrent pas. Le constructeur et les destructeurs doivent être un autre point de révision fort, le dernier pour s'assurer que toute mémoire allouée est libérée.

+0

memcpy n'est pas si dangereux, car il accepte un paramètre de longueur, aussi longtemps que le tampon de destination est synchronisé avec la longueur (les deux devraient être sous le contrôle du développeur), cela n'a pas d'importance si le tampon source est compromis. –

2

Quelle version de Visual Studio utilisez-vous? En 2008, avec toutes les alertes activées, toutes les fonctions que vous mentionnez (et plus) vous avertissent qu'elles sont obsolètes.

Peut-être que vous pourriez vérifier que tous les avertissements sont activés et laisser le compilateur faire le travail dur pour vous?

En note, l'excellent writing secure code explique parfaitement les différents pièges de certaines fonctions plus anciennes.

+0

J'ai ouvert une autre question (http://stackoverflow.com/questions/167199/what-cc-tools-can-check-for-buffer-overflows) qui traite des outils pour m'aider à chercher les fonctions qui peuvent créer des débordements . – MrValdez

2

J'ai un peu le même problème sur la base de code sur laquelle je travaille. Mon conseil: méfiez-vous de toutes les fonctions C qui ressemblent à str *() et mem *(). Méfiez-vous également de tout ce qui prend un pointeur vers un tampon, sans une longueur. Comme il semble que vous ayez la possibilité d'utiliser C++, dans les cas les plus flagrants, j'essaierais d'utiliser des conteneurs C++ pour les choses: vecteur, chaîne, carte, etc. Cela vous facilitera la vie.

De plus, les outils de détection automatique de problèmes sont merveilleux. Si vous pouvez utiliser valgrind, je le recommande. Aussi Rational Purify est extrêmement puissant, mais pas bon marché.

3

La question commence à la mauvaise extrémité, j'ai peur. Il est supposé que les dépassements de tampon se produisent dans d'autres fonctions. La cause la plus fréquente est l'opérateur ++, selon mon expérience, ou encore un manque d'opérateur! =.

La meilleure solution pour trouver un lot de ceux-ci est/GS dans Visual Studio 2005/8. Il ne les trouvera pas tous, mais c'est un moyen peu coûteux de réduire la quantité de travail manuel nécessaire.

5

Valgrind est votre nouveau meilleur ami.

valgrind --tool = memcheck --leak-check = ./a.out complète

1

Un gotcha supplémentaire dans C est la fonction "strncpy()". Beaucoup de gens ne se rendent pas compte qu'il est libre de renvoyer une chaîne qui n'est pas nulle terminée.

+0

+1 [Pourquoi strncpy' n'est pas sûr?] (Http://stackoverflow.com/questions/869883/why-is-strncpy-insecure). En outre, ['strtok' est thread-dangereux] (http://stackoverflow.com/questions/5999418/why-is-strtok-considered-unsafe) et risqué aussi. – legends2k

+0

http://stackoverflow.com/questions/869883/why-is-strncpy-insecure – jdkoftinoff

Questions connexes