c++ - 使用 Visual C++ 进行地址 sanitizer : ignore read buffer overflows while still catching write buffer overflows

标签 c++ visual-c++ buffer-overflow address-sanitizer

考虑以下示例:

int main()
{
    char* p = new char[10];
    
    srand(p[11]); // heap buffer overflow - read

    p[11] = rand(); // heap buffer overflow - write
}

我希望 ASan 目前不要标记堆缓冲区溢出 - 读取,同时仍然标记堆缓冲区溢出 - 写入

我想要这样做的原因是现在集中精力处理更危险的错误。读取溢出要么立即崩溃,要么不会产生任何后果,而写入溢出可能会导致稍后在其他地方触发的损坏。对于一些小的溢出,甚至立即崩溃也被排除。所以我肯定也会研究读取溢出,但稍后。

有办法实现这一点吗?

最佳答案

有两个方向可以实现这一目标。

1。触发错误后继续

要在发生错误后继续,-fsanitize-recover=address应使用选项。来自 FAQ :

Q: Can AddressSanitizer continue running after reporting first error?

A: Yes it can, AddressSanitizer has recently got continue-after-error mode. This is somewhat experimental so may not yet be as reliable as default setting (and not as timely supported). Also keep in mind that errors after the first one may actually be spurious. To enable continue-after-error, compile with -fsanitize-recover=address and then run your code with ASAN_OPTIONS=halt_on_error=0.

MSVC 编译器尚不支持此选项。有一个issue添加它。

如果它有效,可以安装一个自定义处理程序来检查是否有读取或写入错误,忽略读取错误并报告写入错误。

2。不要检测读取错误

正如 @yugr 指出的,有 -mllvm -asan-instrument-reads=false选项来实现这一点。但MSVC编译器也不支持该选项。

但是仍然有一种方法可以避免在某些地方进行编译器检测。是__declspec(no_sanitize_address) 。因此,可以通过隔离已知的读取错误来实现目标,如下所示:

__declspec(no_sanitize_address)
void isolate_read_heap_buffer_overflow(char* p)
{
    srand(p[11]); // heap buffer overflow - read
}

int main()
{
    char* p = new char[10];
    
    isolate_read_heap_buffer_overflow(p);

    p[11] = rand(); // heap buffer overflow - write

    return 0;
}

其他更好的选择

还有clang-cl编译器,实际上是 Clang 支持 Visual C++ 语义。 Visual Studio 安装程序会安装它。因此,如果一个项目可以重新定位以使用 Clang,这将打开 Clang 中可用的所有 Address Sanitizer 功能。不幸的是,重新定位一些遗留代码库可能是一项漫长的任务。

关于c++ - 使用 Visual C++ 进行地址 sanitizer : ignore read buffer overflows while still catching write buffer overflows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69719273/

相关文章:

C++ DLL 函数导出。 DLL 不会保持加载状态

c++ - msvc 相当于 gcc 的 __BASE_FILE__

buffer-overflow - 地址中存在 NULL 字符导致缓冲区溢出

c++ - 继承问题

c++ - 为什么 C++ 使用指针?

c++ - 如何从头文件调用枚举?

c++ - 为什么将引用添加到测试项目后仍然出现 "unresolved external symbol"错误?

Glassfish 3.1 最大 URI 长度

sockets - 是否可以在不使用 Android SDK 管理实用程序的情况下下载 Android SDK 组件?

C++ 包含混淆