Jeu sécurité

Le bug du mois de mai

Proposé par Eric Mittelette

Dans le code suivant, l'utilisation de /GS comme option de compilation en mode release va avoir comme résultat :

(pseudo code)
char chaineinterne[10];
...

void Transfert(const char *str)
{
   strcpy(chaineinterne, str);
}

int Traitement()
{
   ...
   char buffer[] = " nous partîmes 500 mais par un prompt renfort nous nous vîmes 3000 en arrivant au port";
   Transfert (buffer);
   ...
}


La bonne réponse

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.


Pour aller plus loin

Un article à lire : GS/ (contrôle de sécurité de la mémoire tampon)

Un document en anglais 

Consultez la rubrique « Introduction à la sécurité », comportant des articles indispensables et des webcasts pour bien commencer

Le centre de conseils sur la sécurité pour les développeurs

Writing Secure Code, l’ouvrage de référence 

Le règlement | Comment jouer ? | Liste des gagnants


**
**
**
**
**
**