Partager via


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

Capture d’écran du débogueur affichant l’erreur global-buffer-overflow dans l’exemple 1.

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

Capture d’écran du débogueur affichant l’erreur global-buffer-overflow dans l’exemple 2.

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++

Capture d’écran du débogueur affichant l’erreur global-buffer-overflow dans l’exemple 3.

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