Condividi tramite


Errore: global-buffer-overflow

Errore di purificazione dell'indirizzo: overflow del buffer globale

Il compilatore genera metadati per qualsiasi variabile nelle .data sezioni o .bss . Queste variabili hanno l'ambito del linguaggio globale o statico del file. Vengono allocati in memoria prima dell'avvio main() . Le variabili globali in C vengono trattate in modo molto diverso rispetto a in C++. Questa differenza è dovuta alle regole complesse per il collegamento di C.

In C una variabile globale può essere dichiarata in diversi file di origine e ogni definizione può avere tipi diversi. Il compilatore non può visualizzare tutte le definizioni possibili contemporaneamente, ma il linker può. Per C, per impostazione predefinita il linker seleziona la variabile di dimensioni maggiori in tutte le diverse dichiarazioni.

In C++, un oggetto globale viene allocato dal compilatore. Può esistere una sola definizione, quindi le dimensioni di ogni definizione sono note in fase di compilazione.

Esempio: global in 'C' con più definizioni di tipo

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

Per compilare e testare questo esempio, eseguire questi comandi in un prompt dei comandi per sviluppatori di Visual Studio 2019 versione 16.9 o successiva:

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

Errore risultante

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

Esempio: statico a livello di funzione semplice

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

Per compilare e testare questo esempio, eseguire questi comandi in un prompt dei comandi per sviluppatori di Visual Studio 2019 versione 16.9 o successiva:

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

Errore risultante - livello di funzione semplice statico

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

Esempio: tutti gli ambiti globali 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;
}

Per compilare e testare questo esempio, eseguire questi comandi in un prompt dei comandi per sviluppatori di Visual Studio 2019 versione 16.9 o successiva:

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

Errore risultante: tutti gli ambiti globali in C++

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

Vedi anche

Panoramica di AddressSanitizer
Problemi noti di AddressSanitizer
Riferimento alla compilazione e al linguaggio AddressSanitizer
Informazioni di riferimento sul runtime AddressSanitizer
Byte ombreggiatura AddressSanitizer
AddressSanitizer cloud o test distribuiti
Integrazione del debugger AddressSanitizer
Esempi di errore addressSanitizer