Erreur : global-buffer-overflow
Erreur d’assainissement de l’adresse : dépassement global de mémoire tampon
Le compilateur génère des métadonnées pour n’importe quelle variable dans les sections ou .bss
les .data
sections. Ces variables ont une étendue de langage statique globale ou de fichier. Ils sont alloués en mémoire avant main()
de commencer. Les variables globales en C sont traitées beaucoup différemment de celles en C++. Cette différence est due aux règles complexes pour lier C.
En C, une variable globale peut être déclarée dans plusieurs fichiers sources, et chaque définition peut avoir différents types. Le compilateur ne peut pas voir toutes les définitions possibles à la fois, mais l’éditeur de liens peut. Pour C, l’éditeur de liens sélectionne par défaut la variable de taille la plus grande parmi toutes les déclarations différentes.
En C++, un global est alloué par le compilateur. Il ne peut y avoir qu’une seule définition, de sorte que la taille de chaque définition est connue au moment de la compilation.
Exemple : globals dans « C » avec plusieurs définitions de type
// file: a.c
int x;
// file: b.c
char* x;
// file: c.c
float* x[3];
// file: example1-main.c
// global-buffer-overflow error
// AddressSanitizer reports a buffer overflow at the first line
// in function main() in all cases, REGARDLESS of the order in
// which the object files: a.obj, b.obj, and c.obj are linked.
double x[5];
int main() {
int rc = (int) x[5]; // Boom!
return rc;
}
Pour générer et tester cet exemple, exécutez ces commandes dans une invite de commandes développeur Visual Studio 2019 version 16.9 ou ultérieure :
cl a.c b.c c.c example1-main.c /fsanitize=address /Zi
devenv /debugexe example1-main.exe
Erreur résultante
Exemple : statique au niveau de la fonction simple
// example2.cpp
// global-buffer-overflow error
#include <string.h>
int
main(int argc, char **argv) {
static char XXX[10];
static char YYY[10];
static char ZZZ[10];
memset(XXX, 0, 10); memset(YYY, 0, 10); memset(ZZZ, 0, 10);
int res = YYY[argc * 10]; // Boom!
res += XXX[argc] + ZZZ[argc];
return res;
}
Pour générer et tester cet exemple, exécutez ces commandes dans une invite de commandes développeur Visual Studio 2019 version 16.9 ou ultérieure :
cl example2.cpp /fsanitize=address /Zi
devenv /debugexe example2.exe
Erreur résultante - statique au niveau de la fonction simple
Exemple : toutes les étendues globales en C++
// example3.cpp
// global-buffer-overflow error
// Run 4 different ways with the choice of one of these options:
//
// -g : Global
// -c : File static
// -f : Function static
// -l : String literal
#include <string.h>
struct C {
static int array[10];
};
// normal global
int global[10];
// class static
int C::array[10];
int main(int argc, char **argv) {
int one = argc - 1;
switch (argv[1][1]) {
case 'g': return global[one * 11]; //Boom! simple global
case 'c': return C::array[one * 11]; //Boom! class static
case 'f':
{
static int array[10] = {};
return array[one * 11]; //Boom! function static
}
case 'l':
// literal global ptr created by compiler
const char *str = "0123456789";
return str[one * 11]; //Boom! .rdata string literal allocated by compiler
}
return 0;
}
Pour générer et tester cet exemple, exécutez ces commandes dans une invite de commandes développeur Visual Studio 2019 version 16.9 ou ultérieure :
cl example3.cpp /fsanitize=address /Zi
devenv /debugexe example3.exe -l
Erreur résultante : toutes les étendues globales en C++
Voir aussi
Vue d’ensemble de AddressSanitizer
Résoudre les problèmes connus liés à AddressSanitizer
Référence de build et de langage AddressSanitizer
Informations de référence sur le runtime AddressSanitizer
Octets d’ombre AddressSanitizer
Test cloud ou distribué AddressSanitizer
Intégration du débogueur AddressSanitizer
Exemples d’erreur AddressSanitizer