错误:stack-buffer-overflow

地址擦除器错误:堆栈缓冲区溢出

在 C 或 C++ 中,堆栈缓冲区溢出可以通过多种方式发生。 我们为可通过简单的重新编译来捕获的此类错误提供了一些示例。

示例 - 堆栈缓冲区溢出

// example1.cpp
// stack-buffer-overflow error
#include <string.h>

int main(int argc, char **argv) {
    char x[10];
    memset(x, 0, 10);
    int res = x[argc * 10];  // Boom! Classic stack buffer overflow

    return res;
}

若要生成并测试此示例,请在 Visual Studio 2019 版本 16.9 或更高版本的开发人员命令提示符中运行以下命令:

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

生成的错误

示例 1 中显示 stack-buffer-overflow 错误的调试器的屏幕截图。

示例 - 堆栈缓冲区数学

// example2.cpp
// stack-buffer-overflow error
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int main(int argc, char **argv) {
    assert(argc >= 2);
    int idx = atoi(argv[1]);
    char AAA[10], BBB[10], CCC[10];
    memset(AAA, 0, sizeof(AAA));
    memset(BBB, 0, sizeof(BBB));
    memset(CCC, 0, sizeof(CCC));
    int res = 0;
    char *p = AAA + idx;
    printf("AAA: %p\ny: %p\nz: %p\np: %p\n", AAA, BBB, CCC, p);

    return *(short*)(p) + BBB[argc % 2] + CCC[argc % 2];  // Boom! ... when argument is 9
}

若要生成并测试此示例,请在 Visual Studio 2019 版本 16.9 或更高版本的开发人员命令提示符中运行以下命令:

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

生成的错误 - 堆栈缓冲区数学

示例 2 中显示 stack-buffer-overflow 错误的调试器的屏幕截图。

示例 - 堆栈上不正确的向下强制转换

// example3.cpp
// stack-buffer-overflow error
class Parent {
public:
    int field;
};

class Child : public Parent {
public:
    volatile int extra_field;
};

int main(void) {

    Parent p;
    Child *c = (Child*)&p;
    c->extra_field = 42;  // Boom !

    return (c->extra_field == 42);
}

若要生成并测试此示例,请在 Visual Studio 2019 版本 16.9 或更高版本的开发人员命令提示符中运行以下命令:

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

生成的错误 - 堆栈上不正确的向下强制转换

示例 3 中显示 stack-buffer-overflow 错误的调试器的屏幕截图。

另请参阅

AddressSanitizer 概述
AddressSanitizer 已知问题
AddressSanitizer 生成和语言参考
AddressSanitizer 运行时参考
AddressSanitizer 阴影字节
AddressSanitizer 云或分布式测试
AddressSanitizer 调试程序集成
AddressSanitizer 错误示例