La bonne réponse est : Grace à /GS, l’exécution est interrompue lors du retour de la fonction, une erreur est retournée, et donc le buffer overrun ne peut être exploité alors qu’il est effectivement apparu.
Plusieurs options sont possibles :
| • | Utilisation des versions sécurisées des fonctions de la runtime C. Par exemple dans notre cas, utiliser strcpy_s(…) qui lèvera une exception en cas de débordement lors de la copie. | | • | Travail sur l’algorithme du code, ie faire du buffer chaineinterne un buffer dynamique et réallouer de la mémoire afin qu’il soit assez grand pour recevoir la chaine passée en paramètre. | | • | Travail sur l’algorithme du code, et vérifier la taille des buffers saisie par l’utilisateur pour respecter la taille prévue de chaineinterne | | • | Travail avec /GS et un gestionnaire d’exception capable d’alerter l’utilisateur que la saisie n’est pas correcte… |
/GS est une option de compilation du C++ apparue avec la version 7.0 du compilateur (VS2002). Cette option continue d’évoluer de version en version sur des points assez fins (pointeur de fonction par exemple en VS2005).
L’objectif de cette option est d’ajouter à chaque appel de fonction manipulant des buffer un cookie en début de pile (historiquement canari, car évoquant le travail des mineurs d’autrefois et les risques de grisou) et un cookie en fin de pile.
Au retour de la fonction, lorsque l’on dépile les arguments de la pile, une vérification de ces cookies est effectuée.
Si les valeurs n’ont pas changé, c’est qu’à priori tout c’est bien passé (pas de buffer overrun/overflow). Par contre si les valeurs ont été altérées, cela signifie qu’il a eu un problème dans la fonction et qu’un buffer overrun a eu lieu. Auquel cas une exception va être levée et l’exécution stoppée.
/GS n’empêche donc pas qu’un buffer overrun se produise, mais détecte qu’un problème est apparu et l’on stoppe l’exécution.
Le fait de lever une exception et d’interrompre l’exécution prévient alors l’exploitation de ce buffer overrun.
|