Dans mon esprit simplet, un compilateur qui modifie le comportement d'un programme, ça se nomme nomme bug.
Il ne modifie pas le comportement du programme, dans le sens où du point de vue formel, il n'a rien fait d'illégal. Voici un autre exemple, plus simple :
void dummy(double *array, size_t len) {
double acc = 0.0;
for (int i = 0; i < len; ++i)
__acc += array[i];
}
Un bon compilateur, qui optimise bien, va tout simplement supprimer la boucle (et avec l'inlining, il ne subsistera plus rien du code original). Un mec qui voudrait (par exemple) utiliser dummy() pour flusher arbitrairement la mémoire cache ne pourrait plus le faire.
Autre exemple : memset fait partie des fonctions standard du C. À ce titre, elle est donc « magique », et le compilateur peut faire un peu ce qu'il veut avec du moment que ça ne viole pas les contraintes du programme. Si par exemple je tape un code du genre (piqué à Marc Espie sur fclc) void f() {
char passwd[250];
// code qui demande un mot de passe a l'utilisateur.
// code qui s'en sert
memset(passwd, 0, sizeof passwd);
}
Ben là, le compilateur peut dire « hé mais de toute manière, passwd est local à la fonction, donc faire un memset dessus ça prend du temps et des ressources pour rien ». Et paf, il le vire. Sauf qu'en fait, le memset était là pour éviter qu'un petit malin essaie ensuite de lire dans la zone mémoire où passwd est alloué (par exemple pour lire une ancienne valeur de passwd). Du point de vue du « sens » du programme, tout est respecté. Du point de vue sécurité, c'est une « catastrophe ».
[^] # Re: Je ne comprends pas
Posté par lasher . En réponse à la dépêche Exploit local dans le noyau Linux 2.6.30. Évalué à 6.
Il ne modifie pas le comportement du programme, dans le sens où du point de vue formel, il n'a rien fait d'illégal. Voici un autre exemple, plus simple :
void dummy(double *array, size_t len) {double acc = 0.0;
for (int i = 0; i < len; ++i)
__acc += array[i];
}
Un bon compilateur, qui optimise bien, va tout simplement supprimer la boucle (et avec l'inlining, il ne subsistera plus rien du code original). Un mec qui voudrait (par exemple) utiliser dummy() pour flusher arbitrairement la mémoire cache ne pourrait plus le faire.
Autre exemple : memset fait partie des fonctions standard du C. À ce titre, elle est donc « magique », et le compilateur peut faire un peu ce qu'il veut avec du moment que ça ne viole pas les contraintes du programme. Si par exemple je tape un code du genre (piqué à Marc Espie sur fclc)
void f() {char passwd[250];
// code qui demande un mot de passe a l'utilisateur.
// code qui s'en sert
memset(passwd, 0, sizeof passwd);
}
Ben là, le compilateur peut dire « hé mais de toute manière, passwd est local à la fonction, donc faire un memset dessus ça prend du temps et des ressources pour rien ». Et paf, il le vire. Sauf qu'en fait, le memset était là pour éviter qu'un petit malin essaie ensuite de lire dans la zone mémoire où passwd est alloué (par exemple pour lire une ancienne valeur de passwd). Du point de vue du « sens » du programme, tout est respecté. Du point de vue sécurité, c'est une « catastrophe ».