Delen via


Fout: global-buffer-overflow

Fout bij opschoning van adres: globale bufferoverloop

Opmerkingen

De compiler genereert metagegevens voor elke variabele in de .data of .bss secties. Deze variabelen hebben een taalbereik van globaal of statisch bestand. Ze worden toegewezen in het geheugen voordat main() ze worden gestart. Globale variabelen in C worden veel anders behandeld dan in C++. Dit verschil komt door de complexe regels voor het koppelen van C.

In C kan een globale variabele worden gedeclareerd in verschillende bronbestanden, en elke definitie kan verschillende typen hebben. De compiler kan niet alle mogelijke definities tegelijk zien, maar de linker wel. Voor C wordt de linker standaard ingesteld op het selecteren van de variabele van de grootste grootte uit alle verschillende declaraties.

In C++wordt een globaal toegewezen door de compiler. Er kan slechts één definitie zijn, dus de grootte van elke definitie is bekend tijdens het compileren.

Voorbeeld: globals in 'C' met meerdere typedefinities

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

Als u dit voorbeeld wilt bouwen en testen, voert u deze opdrachten uit in een Opdrachtprompt voor ontwikkelaars van Visual Studio 2019 versie 16.9 of hoger:

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

Resulterende fout

Schermopname van het foutopsporingsprogramma met de fout global-buffer-overflow in voorbeeld 1.

Voorbeeld: statisch op functieniveau eenvoudig

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

Als u dit voorbeeld wilt bouwen en testen, voert u deze opdrachten uit in een Opdrachtprompt voor ontwikkelaars van Visual Studio 2019 versie 16.9 of hoger:

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

Resulterende fout- statisch op functieniveau

Schermopname van het foutopsporingsprogramma met de fout global-buffer-overflow in voorbeeld 2.

Voorbeeld: alle globale bereiken 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] = {};
        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;
}

Als u dit voorbeeld wilt bouwen en testen, voert u deze opdrachten uit in een Opdrachtprompt voor ontwikkelaars van Visual Studio 2019 versie 16.9 of hoger:

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

Resulterende fout: alle globale bereiken in C++

Schermopname van het foutopsporingsprogramma met de fout global-buffer-overflow in voorbeeld 3.

Zie ook

Overzicht van AddressSanitizer
AddressSanitizer bekende problemen
AddressSanitizer-build- en taalreferenties
naslaginformatie over AddressSanitizer-runtime
addressSanitizer schaduwbytes
AddressSanitizer-cloud of gedistribueerde tests
integratie van AddressSanitizer-foutopsporingsprogramma's
voorbeelden van AddressSanitizer-fouten