• Aucun résultat trouvé

Acc`es hors limite dans un tableau (local ou global) de taille fixe 104

Dans le document The DART-Europe E-theses Portal (Page 119-124)

Partie II Contributions 65

Chapitre 5 Impl´ ementation 99

5.3 Traduction des conditions d’erreurs

5.3.2 Acc`es hors limite dans un tableau (local ou global) de taille fixe 104

Pour un acc`es tableau en g´en´eral, si l’analyse de valeur ne peut pas garantir que c’est un acc`es valide, c’est-`a-dire que la valeur consult´ee ou modifi´ee entre dans les bornes du tableau, elle ajoute une assertion avec, comme condition, la condition qui emp`eche l’acc`es hors limite. Dans le cas d’un tableau de taille fixe, l’analyse de valeur connaˆıt la taille du tableau et il est facile d’´etablir la condition de sˆuret´e entre l’indice d’acc`es et la taille du tableau correspondant.

Pour l’exemple elemInArray pr´esent´e dans la figure 5.3, l’analyse de valeur ne peut pas garantir que a est un indice valide dansT. Il ajoute donc l’assertion :

// a s s e r t (0 <= a ∧ a < 1 0 ) ;

avant la ligne 4.

Dans ce cas aussi, la traduction de la condition est directe. Il suffit de prendre la n´egation de la condition donn´ee par l’assertion. L’instruction conditionnelle qui remplace l’instruction mena¸cante est :

i f(!(0 <= a && a < 10)) error ();

e l s e

y = T [ a ];

5.3. Traduction des conditions d’erreurs 1 char e l e m I n S t r(char * str , i n t a ){

2 char y ;

3 y = *( str + a );

4 return y ; 5 }

Figure 5.4 – Exemple avec un acc`es pointeur 1 char e l e m I n S t r(char * str , i n t a ){

2 char y ;

31 i f( p a t h c r a w l e r _ l e n g t h( str ) <= a || a < 0 )

32 error ();

33 e l s e

3 y = *( str + a );

4 return y ; 5 }

Figure 5.5 – L’exemple de la figure 5.4 apr`es l’ajout des branches d’erreur

5.3.3 Pointeur invalide ou acc` es hors limite dans un tableau de taille variable

On consid`ere dans cette partie les tableaux de taille variable et les pointeurs globaux ou locaux ainsi que tout tableau ou pointeur en entr´ee d’une fonction. En effet, la taille d’un tableau en entr´ee est perdue par CIL, conform´ement `a la norme C.

Pour un acc`es par pointeur, ou dans un tableau de taille variable, si l’analyse de valeur ne connaˆıt pas la taille exacte du tableau consult´e, et trouve un risque d’acc`es invalide, elle ajoute une assertion avec, comme condition, la condition qui emp`eche l’acc`es invalide.

Mais, dans ce cas, elle utilise la commande ACSL \valid.

Pour l’exemple elemInStr pr´esent´e dans la figure 5.4, si l’analyse de valeur ne peut pas garantir que a est un indice valide dans str, elle ajoute avant la ligne 3 l’assertion :

// @assert \v a l i d ( s t r + a ) ;

Dans ce cas, la condition qui provoque l’erreur d´epend de la taille allou´ee pour str dans chaque cas de test. Cette taille fait partie des donn´ees de test qui doivent ˆetre d´e-termin´ees par PathCrawler. Nous allons voir comment nous ´etendonsPathCrawler afin de lui permettre de r´ecup´erer la taille des tableaux donn´es en entr´ee, `a l’aide de la fonction nomm´ee pathcrawler_length d´ecrite ci-dessous.

Grˆace `a cette extension, la condition d’erreur sera simplement remplac´ee par : p a t h c r a w l e r _ l e n g t h ( str ) <= a || a < 0

1 s t r u c t _ _ p a t h c r a w l e r _ a r r a y { 2 void* ptr ;

3 size_t length ;

4 size_t e l e m e n t _ s i z e;

5 s t r u c t _ _ p a t h c r a w l e r _ a r r a y * next ; 6 };

7 s t r u c t _ _ p a t h c r a w l e r _ a r r a y * _ _ p a t h c r a w l e r _ f i r s t _ a r r a y = NULL ;

Figure 5.6 – La structure__pathcrawler_array

ce qui la rend ex´ecutable lors de l’ex´ecution concr`ete et fera le lien avec la taille du tableau allou´e lors de l’ex´ecution symbolique. Le programme apr`es l’ajout des branches d’erreur est pr´esent´e dans la figure 5.5.

Extension pour la taille des tableaux pass´es en param`etres

Pour traiter les alarmes sur les tableaux (et pointeurs) en entr´ee de la fonction sous test, on a besoin de connaˆıtre la taille du tableau donn´e en entr´ee. Cependant, le langage C ne nous permet pas de connaˆıtre la taille des tableaux donn´es en entr´ee d’une fonction.

En effet, la taille d’un tableau allou´e dynamiquement n’est pas r´ecup´erable dans le code C apr`es son allocation.

Rappelons que la fonction sizeof donne bien le nombre d’octets occup´es par un ta-bleau de taille fixe. Mais un tata-bleau de taille variable est consid´er´e comme un pointeur, dont la taille est de quatre octets utilis´es pour stocker l’adresse de la zone point´ee (sur une machine 32 bits).

Nous ´etendonsPathCrawlerafin de lui permettre de r´ecup´erer la taille des tableaux en entr´ee d’une fonction, en le dotant de la fonctionpathcrawler_length. En effet, nous surchargeons les fonctions d’allocation et de lib´eration de m´emoire afin de sauvegarder la taille allou´ee `a chaque fois. La fonctionpathcrawler_lengthprend un pointeur en entr´ee et permet de r´ecup´erer la taille allou´ee pour ce pointeur pass´e en param`etre. Dans ce qui suit, nous expliquons les modifications apport´ees en d´etails.

Parmi les rˆoles du lanceur, il y a l’allocation de la m´emoire n´ecessaire aux entr´ees de la fonction sous test (voir section 3.3.3). Nous lui ajoutons une nouvelle fonctionnalit´e, qui consiste `a enregistrer la taille des tableaux allou´es dynamiquement par le lanceur avant un cas de test, afin que nous puissions la restituer ensuite par la fonction pathcraw-ler_length. Pour cela, nous modifions l’impl´ementation des deux fonctions pathcraw-ler_alloc etpathcrawler_free, dont les rˆoles initiaux ´etaient respectivement d’allouer et de lib´erer la zone m´emoire n´ecessaire pour chaque param`etre.

Nous ajoutons une variable globale __pathcrawler_first_array qui pointe vers une

5.3. Traduction des conditions d’erreurs

liste chaˆın´ee contenant les descripteurs des tableaux allou´es. Chaque ´el´ement de la liste instancie la structure __pathcrawler_array pr´esent´ee dans la figure 5.6. Cette structure contient le descripteur d’un tableau allou´e et inclut quatre champs :

– le premier contient l’adresse de la zone m´emoire allou´ee pour le tableau, – le champ length correspond au nombre d’´el´ements dans ce tableau, – le champ element_size correspond `a la taille de chaque ´el´ement et – le champ nextfait r´ef´erence au prochain ´el´ement de la liste chaˆın´ee.

Notre nouvelle impl´ementation depathcrawler_allocest pr´esent´ee dans la figure 5.7.

Elle commence par allouer un ´el´ement pour stocker un nouveau descripteur de tableau (ligne 3). Ensuite on alloue la m´emoire n´ecessaire pour le tableau (ligne 6). On cherche la place du descripteur dans la liste (lignes 12–13). On initialise les informations du descrip-teur (lignes 14–17). On place le descripdescrip-teur dans la liste et on retourne le tableau allou´e.

Notre nouvelle impl´ementation depathcrawler_free est pr´esent´ee dans la figure 5.8.

Elle cherche le descripteur correspondant `a ce tableau dans la liste des descripteurs (lignes 3–4). La ligne 7 relie l’´el´ement pr´ec´edent `a l’´el´ement suivant de descripteur du tableau `a lib´erer. On lib`ere le descripteur (ligne 8) et ensuite on lib`ere la zone m´emoire allou´ee pour le tableau (lignes 9–10).

La fonctionpathcrawler_length est pr´esent´ee dans la figure 5.9. Elle cherche le

des-1 void* p a t h c r a w l e r _ f r e e(void* ptr )) {

2 s t r u c t _ _ p a t h c r a w l e r _ a r r a y ** pnext = & _ _ p a t h c r a w l e r _ f i r s t _ a r r a y ; 3 while (* pnext != NULL && (* pnext ) - > ptr < ptr )

4 pnext = &((* pnext ) - > next );

5 i f (* pnext != NULL && (* pnext ) - > ptr == ptr ) { 6 s t r u c t _ _ p a t h c r a w l e r _ a r r a y * current = * pnext ; 7 * pnext = current - > next ;

8 free ( current );

9 i f ( ptr != NULL )

10 free ( ptr );

11 }

12 return;

13 }

Figure 5.8 – La fonction pathcrawler_free

1 i n t p a t h c r a w l e r _ l e n g t h(void* ptr ) {

2 s t r u c t _ _ p a t h c r a w l e r _ a r r a y * cur = _ _ p a t h c r a w l e r _ f i r s t _ a r r a y ; 3 while ( cur != NULL && cur - > ptr < ptr ) {

4 cur = cur - > next ;

5 }

6 i n t len = 0;

7 i f ( cur != NULL && cur - > ptr == ptr ) { 8 len = cur - > length ;

9 }

10 return len ; 11 }

Figure 5.9 – La fonction pathcrawler_length

5.4. Traitement des exceptions

Dans le document The DART-Europe E-theses Portal (Page 119-124)