Kesalahan: global-buffer-overflow

Kesalahan Pembersih Alamat: Luapan buffer global

Komentar

Pengkompilasi menghasilkan metadata untuk variabel apa pun di bagian .data atau .bss . Variabel ini memiliki cakupan bahasa statis global atau file. Mereka dialokasikan dalam memori sebelum main() dimulai. Variabel global dalam C diperlakukan jauh berbeda dari di C++. Perbedaan ini karena aturan yang kompleks untuk menautkan C.

Dalam C, variabel global dapat dideklarasikan dalam beberapa file sumber, dan setiap definisi dapat memiliki jenis yang berbeda. Pengkompilasi tidak dapat melihat semua definisi yang mungkin sekaligus, tetapi linker dapat. Untuk C, linker default untuk memilih variabel berukuran terbesar dari semua deklarasi yang berbeda.

Di C++, global dialokasikan oleh pengkompilasi. Hanya ada satu definisi, sehingga ukuran setiap definisi diketahui pada waktu kompilasi.

Contoh - global di 'C' dengan beberapa definisi jenis

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

Untuk membuat dan menguji contoh ini, jalankan perintah ini di perintah Visual Studio 2019 versi 16.9 atau yang lebih baru:

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

Kesalahan yang dihasilkan

Cuplikan layar debugger yang menampilkan kesalahan global-buffer-overflow dalam contoh 1.

Contoh - tingkat fungsi sederhana statis

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

Untuk membuat dan menguji contoh ini, jalankan perintah ini di perintah Visual Studio 2019 versi 16.9 atau yang lebih baru:

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

Kesalahan yang dihasilkan - tingkat fungsi sederhana statis

Cuplikan layar debugger yang menampilkan kesalahan global-buffer-overflow dalam contoh 2.

Contoh - semua cakupan global di 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;
}

Untuk membuat dan menguji contoh ini, jalankan perintah ini di perintah Visual Studio 2019 versi 16.9 atau yang lebih baru:

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

Kesalahan yang dihasilkan - semua cakupan global di C++

Cuplikan layar debugger yang menampilkan kesalahan global-buffer-overflow dalam contoh 3.

Lihat juga

Gambaran umum AddressSanitizer
Masalah yang diketahui AddressSanitizer
Referensi bahasa dan build AddressSanitizer
Referensi runtime AddressSanitizer
Byte bayangan AddressSanitizer
AddressSanitizer cloud atau pengujian terdistribusi
Integrasi debugger AddressSanitizer
Contoh kesalahan AddressSanitizer