Mohamed MESSIKH & Nelson NKAWA - M2 CSI - 2021/2022
# Rapport TP Cours SCLAM
## Partie 2
### Exercice 1:
Dans l'exemple 1 fourni, on a une fonction qui prend une valeur en paramètre et va vérifier la valeur de cette variable pour ajouter des données dans un tableau.
```
void f (int i) {
int T[10] ;
if (i>10)
if (i+5<20)
T[i] = 42 ;
else
if (i>0) T[i] = 0 ;
}
```
3 cas de tests ont été retournés par l'outil PathCrawler. Dans le premier cas, on observe que la valeur de l'entrée prédite de l'entrée est inférieur ou égal à 10 et vaut -190204 ce qui a provoqué un coverage. Il n'a dont pas pu exécuté les autres boucles suivantes comme le montre la figure ci-dessous.

Dans le deuxième cas, il va exécuter la première boucle mais pas la deuxième car i vaut 1161100771 ce qui est très supérieur à 20. Mais dans la dernière branche, l'outil indique une erreur de contexte car on fait un buffer overflow sur la taille du tableau.

Sur le troisième cas de test, la valeur de i valant 11, la première prédiction va passer. La seconde va générer une anomalie du à un buffer overflow sur la taille du tableau.
#### Question 2:
Il nous est demandé de modifier le programme et d'y ajouter un chemin d'exécution non faisable. On a ajouté un chemin après la dernière boucle comme le montre le bout de code suivant:
```
void f (int i) {
int T[10] ;
if (i>10)
if (i+5<20)
T[i] = 42 ;
else
if (i>0) T[i] = 0 ;
/* Notre bout de code ajouté*/
else
T[10000] = 23;
}
```
On a rechargé notre nouveau fichier .tar et avons obtenu toujours 3 cas de test. Dans le premier cas la valeur de i est 37572. Le chemin prédit (i>0) passe mais génère un crash car on dépasse très largement la taille du tableau. On remarque aussi que notre chemin ajouté n'a pas été fait.

Les deux autres sont les memes que dans la question precedente (chemin i <10 et (chemin i > 10 && (i+5)<20)). On observe le meme comportement que celui precedent le non test de notre chemin ajoouté.
Une autre modification a été faite comme le montre le bout de code ci-dessous:
```
void f (int i) {
int T[10] ;
if (i>10)
if (i+5<20)
T[i] = 42 ;
else
if (i>0) T[i] = 0 ;
/* Bout de code ajouté */
if (i<0 && i>10)
for(i=0;i<10000;i++)
T[i]=32;
}
```
Pour celui-ci, on a eu 4 cas de test. Le 4ième cas est du au chemin "if (i<0 && i>10)" dont i vaut -203331. Elle va dont passer le premier chemin prédit (i<0) et pas le second (i>10) comme le montre la figure ci-dessous:

La remarque faite est que pour les 4 cas de test, le chemin pour la boucle for n'est pas fait.
### Exercice 2:
Dans le fichier example2.c, on a 4 fonctions f, g, h, k contenant un tableau T. Ces 4 fonctions testées sous l'outil PathCrawler nous donne les résultats suivants :
#### Fonction f
Pour la fonction f, 3 cas de tests sont générés. Les cas de tests 1 et 3 sont interrompus ( SIGABRT - Process abort signal).
Explication cas 1 :
la première partie de l'assertion est activée avec une valeur négative et la seconde partie de l'assertion est ignorée.
Le prédicat est i>=10 et la valeur choisie par le solveur est un nombre positif très grand i = 196987.
Or nous avons une assertion (i<10 && i>=0) sur la valeur de i qui doit être strictement inférieur à 10. La première partie de l'assertion interrompt l'exécution du programme.

Explication cas 3 : Le predicat est i >=10. La valeur choisie est un nombre négatif très grand i = -448652482.
Ici, c'est la seconde partie de l'assertion qui interrompt l'exécution du programme.

Explication cas 2:
Le prédicat est est i<10 et i>=0.
La valeur de i choisie pour le cas de test est 0.
Pour i=0, l'outil PathCrawler ne sait pas déterminer le comportement de la fonction f. Il s'agit d'une limite de l'outil.

#### Fonction g
L'outil PathCrawler rejette le code de la fonction g et n'est pas en mesure de générer des cas de tests (message d'erreur lors de la génération des cas de tests).
En effet, le code de la fonction g est linéaire, sans instruction conditionnelle (ni assert, ni if, etc.). C'est une limitation de l'outil PathCrawler.
#### Fonction h
Pour la fonction g, 2 cas de tests sont générés.
Cas 1:
Ici, le predicat est i>=11. Pour le cas de test généré la valeur de i choisie est 63545.
L'outil PathCrawler renvoie un verdict inconnu. L'outil PathCrawler n'est pas capable de déterminer qu'il y a un Buffer Overflow du tableau T.

Cas 2:
Ici, le predicat est i<11. Pour le cas de test généré la valeur de i choisie est 0.
L'outil PathCrawler renvoie un verdict inconnu. Il s'agit d'une limitation de l'outil PC car l'affectation T[0]=0 ne pose pas de problème. Par ailleurs, l'outil n'est pas capable de détecter le bug potentiel avec un Buffer Overflow pour une valeur de i=10.
En effet, la condition devrait être ici *if (i<10)* et non *if (i<11)* pour se protéger du Buffer Overflow.

#### Fonction k
Pour la fonction k, 3 cas de tests sont générés et leur exécution est interrompue. Les cas de tests 1 et 3 sont interrompus par signal de type SIGSEGV - Invalid memory reference, et le cas 2 par SIGABRT - Process abort signal.
Cas 1 :
Ici, le predicat est i<0. Pour le cas de test généré la valeur de i choisie est -24960.
Le cas de test 1 est interrompu (SIGSEGV - Invalid memory reference) car la première partie de l'assertion i<0 génère l'interruption (SIGSEV). L'outil PathCrawler détecte bien le bug pour la valeur de i.

Cas 2 :
Ici, le predicat est i>=0 et i<10. Pour le cas de test généré la valeur de i choisie est 0.
Le cas de test 2 est interrompu (SIGABRT - Process abort signal).
Il s'agit probablement d'une limitation de l'outil.

Cas 3:
Ici, le predicat est i>=0 et i>=10. Pour le cas de test généré la valeur de i choisie est 533686555.
Le cas de test 1 est interrompu (SIGSEGV - Invalid memory reference) car la seconde partie de l'assertion i>=10 génère l'interruption (SIGSEV).
L'outil PathCrawler détecte bien le bug pour la valeur de i.

### Exercice 3:
Dans cette partie, nous allons observer 3 scénarios.
#### Premier scénario : *vulnerability induced by an arithmetic overflow*
Dans le programme ci-dessous, nous allons effectuer des calculs numériques sur des char signés. La vulnérabilité ici est du au calcul de la somme de i et j. Les char allant de 0 à 127, cela va dépasser la taille des char et nous donner un résultat négatif ce qui conduit à la vulnérabilité.
```
#include<stdio.h>
int main(char j){
char i=100, sum;
if(j<128)
sum = j - i;
if(j>128)
sum = i+j; // interger overflow
}
```
1 seul cas de test nous a été retourné par l'outil. Dans celui-ci, on constate que seul la première boucle est exécutée avec pour valeur prédite -71 comme le montre la figure ci-dessous.

Il a donc pas exécuté la boucle avec la variable qui sort de la taille d'un *char*.
#### Deuxième scénario : *vulnerabilty not found by PathCrawler because of a non decidable constraints*
#### Troisième scénario : *vulnerability inside a loop body*
Dans le code ci-dessous, une vulnérabilité lié à la valeur de la variable d'entrée x, peut créer un buffer overflow si la valeur de la variable est supérieur à la taille du tableau.
```
#include <stdio.h>
int main (int x)
{
int t[12] ;
int i;
for (i=0; i<x; i++)
t[i]= 42;
}
```

D'après l'analyse, 6 cas de test se sont avérés critiques. Cela est du à la vaaleur de la variable x très supérieur à la taille du tableau. Parmi les 19 cas de test, seul 1 seul dont la valeur prédite de x était 0, n'a pas exécuté la boucle.
#### Quatrième scénario : *vulnerability occurring after a "for" loop with a fixed number of iteration*
On a modifié le programme précedent dans le but de fixé le nombre d'occurance de la boucle for. On voudrait dans ce cas écrire modifier le contenu de la variable *val*. On a dont fait une itération qui va dépasser de plus 1 la taille du tableau comme le montre le code suivant.
```
#include <stdio.h>
int main ()
{
int tab[8] ;
int val = 12;
int i;
for (i=0; i<9; i++)
tab[i]= 42;
}
```
L'analyse avec l'outil *pathcrawler* nous a montrer un cas de test critique qui n'est autre que celle lié à l'écrasement de la valeur de *val* à la fin de l'itération.

#### Cinquième scénario :*vulnerability occurring after a "for" loop with a variable number of iteration*
Nous avons implémenté ce scénario dans le ***troisième scénario***. Comme expliqué dans ce dernier, la valeur de *x* est variable et cette valeur est utilisée dans la boucle *for*. En fonction de la valeur prédite par l'outil *pathcrawler*, cela nous a généré des cas de test très critique losque la valeur de x sera supérieur à la taille du tableau comme le montre la figure ci-dessous.
