Fehler: global-buffer-overflow

Adressbereinigungsfehler: Globaler Pufferüberlauf

Der Compiler generiert Metadaten für jede Variable in den .data oder .bss Abschnitten. Diese Variablen weisen den Sprachumfang globaler oder dateistatischer Variablen auf. Sie werden vor dem Start im Arbeitsspeicher main() zugewiesen. Globale Variablen in C werden viel anders behandelt als in C++. Dieser Unterschied liegt aufgrund der komplexen Regeln für die Verknüpfung von C.

In C kann eine globale Variable in mehreren Quelldateien deklariert werden, und jede Definition kann unterschiedliche Typen aufweisen. Der Compiler kann nicht alle möglichen Definitionen gleichzeitig sehen, aber der Linker kann. Bei C wird der Linker standardmäßig für die Auswahl der variablen der größten Größe aus allen verschiedenen Deklarationen verwendet.

In C++ wird vom Compiler eine globale Zuordnung zugewiesen. Es kann nur eine Definition geben, sodass die Größe jeder Definition zur Kompilierungszeit bekannt ist.

Beispiel : Globalen in "C" mit mehreren Typdefinitionen

// 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; 
}

Um dieses Beispiel zu erstellen und zu testen, führen Sie diese Befehle in einer Visual Studio 2019, Version 16.9 oder einer späteren Entwickler-Eingabeaufforderung, aus:

cl a.c b.c c.c example1-main.c /fsanitize=address /Zi
devenv /debugexe example1-main.exe

Resultierender Fehler

Screenshot of debugger displaying global-buffer-overflow error in example 1.

Beispiel – einfache Funktionsebene statisch

// 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;
}

Um dieses Beispiel zu erstellen und zu testen, führen Sie diese Befehle in einer Visual Studio 2019, Version 16.9 oder einer späteren Entwickler-Eingabeaufforderung, aus:

cl example2.cpp /fsanitize=address /Zi
devenv /debugexe example2.exe

Resultierender Fehler – statische Funktionsebene

Screenshot of debugger displaying global-buffer-overflow error in example 2.

Beispiel : alle globalen Bereiche in 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];
        memset(array, 0, 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;
}

Um dieses Beispiel zu erstellen und zu testen, führen Sie diese Befehle in einer Visual Studio 2019, Version 16.9 oder einer späteren Entwickler-Eingabeaufforderung, aus:

cl example3.cpp /fsanitize=address /Zi
devenv /debugexe example3.exe -l

Resultierender Fehler – alle globalen Bereiche in C++

Screenshot of debugger displaying global-buffer-overflow error in example 3.

Siehe auch

Übersicht über AddressSanitizer
Bekannte Probleme von AddressSanitizer
Kompilierungs- und Sprachreferenz für AddressSanitizer
Runtimereferenz für AddressSanitizer
AddressSanitizer-Schattenbytes
AddressSanitizer-Tests in der Cloud oder verteilten Umgebungen
Integration des AddressSanitizer-Debuggers
AddressSanitizer-Fehlerbeispiele