gcc自带sanitizer工具使用

Sanitizers是谷歌发起的开源工具集,包括了AddressSanitizer, MemorySanitizer, ThreadSanitizer, LeakSanitizer,Sanitizers项目本是LLVM项目的一部分,但GNU也将该系列工具加入到了自家的GCC编译器中。GCC从4.8版本开始逐步支持 Sanitizer,这些工具都是查找隐藏Bug的利器。

AddressSanitizer可用于检测 memory out-of-bounds 和 use-after-free。

  • AddressSanitizer , a fast memory error detector, has been added and can be enabled via -fsanitize=address. Memory access instructions will be instrumented to detect heap-, stack-, and global-buffer overflow as well as use-after-free bugs. To get nicer stacktraces, use -fno-omit-frame-pointer. The AddressSanitizer is available on IA-32/x86-64/x32/PowerPC/PowerPC64 GNU/Linux and on x86-64 Darwin.
  • ThreadSanitizer has been added and can be enabled via -fsanitize=thread. Instructions will be instrumented to detect data races. The ThreadSanitizer is available on x86-64 GNU/Linux.

摘自 https://gcc.gnu.org/gcc-4.8/changes.html

  • AddressSanitizer, a fast memory error detector, is now available on ARM.
  • UndefinedBehaviorSanitizer (ubsan), a fast undefined behavior detector, has been added and can be enabled via -fsanitize=undefined. Various computations will be instrumented to detect undefined behavior at runtime. UndefinedBehaviorSanitizer is currently available for the C and C++ languages.

摘自 https://gcc.gnu.org/gcc-4.9/changes.html

stack-buffer-overflow

/**
 * Copyright (c) 2021 junfu0903@aliyun.com.
 *
 * Unpublished copyright. All rights reserved. This material contains
 * proprietary information that should be used or copied only within
 * junfu0903@aliyun.com, except with written permission of junfu0903@aliyun.com.
 *
 * @file stack_buffer_overflow.c
 * @brief
 * @author junfu0903@aliyun.com
 * @version 1.0.0
 * @date 2021-06-15 10:16:45
 */

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
    int arr[8] = {0};
    arr[0] = 10;
    arr[9] = 11;

    return 0;
}

gcc -g -fsanitize=address stack_buffer_overflow.c -o stack_buffer_overflow

在这里插入图片描述

heap-use-after-free

/**
 * Copyright (c) 2021 junfu0903@aliyun.com.
 *
 * Unpublished copyright. All rights reserved. This material contains
 * proprietary information that should be used or copied only within
 * junfu0903@aliyun.com, except with written permission of junfu0903@aliyun.com.
 *
 * @file heap_use_after_free.c
 * @brief
 * @author junfu0903@aliyun.com
 * @version 1.0.0
 * @date 2021-06-15 10:18:45
 */

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
    char *p = NULL;

    p = (char*)malloc(16);

    free(p);

    p[0] = 1;

    return 0;
}
gcc -g -fsanitize=address heap_use_after_free.c -o heap_use_after_free

在这里插入图片描述

heap-buffer-overflow

/**
 * Copyright (c) 2021 junfu0903@aliyun.com.
 *
 * Unpublished copyright. All rights reserved. This material contains
 * proprietary information that should be used or copied only within
 * junfu0903@aliyun.com, except with written permission of junfu0903@aliyun.com.
 *
 * @file heap_buffer_overflow.c
 * @brief
 * @author junfu0903@aliyun.com
 * @version 1.0.0
 * @date 2021-06-15 10:18:45
 */

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
    char *p = NULL;

    p = (char*)malloc(16);

    p[17] = 12;

    free(p);

    return 0;
}
gcc -g -fsanitize=address heap_buffer_overflow.c -o heap_buffer_overflow

在这里插入图片描述

stack-use-after-scope

/**
 * Copyright (c) 2021 junfu0903@aliyun.com.
 *
 * Unpublished copyright. All rights reserved. This material contains
 * proprietary information that should be used or copied only within
 * junfu0903@aliyun.com, except with written permission of junfu0903@aliyun.com.
 *
 * @file address_use_after_scope.c
 * @brief
 * @author junfu0903@aliyun.com
 * @version 1.0.0
 * @date 2021-06-15 11:37:28
 */

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
    char *ptr;

    {
        char my_char;
        ptr = &my_char;
    }

    *ptr = 123;
    return *ptr;
}
gcc -g -fsanitize=address address_use_after_scope.c -o address_use_after_scope

在这里插入图片描述

data-race

/**
 * Copyright (c) 2021 junfu0903@aliyun.com.
 *
 * Unpublished copyright. All rights reserved. This material contains
 * proprietary information that should be used or copied only within
 * junfu0903@aliyun.com, except with written permission of junfu0903@aliyun.com.
 *
 * @file data_race.c
 * @brief
 * @author junfu0903@aliyun.com
 * @version 1.0.0
 * @date 2021-06-11 18:35:26
 */

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

int g;

void* func(void* arg)
{
    g = 1;
    return NULL;
}

int main(int argc, char** argv)
{
    pthread_t tid;
    pthread_create(&tid, NULL, func, NULL);
    g = 2;
    pthread_join(tid, NULL);

    return 0;
}
gcc -g -fsanitize=thread data_race.c -pthread -o data_race

在这里插入图片描述

memory-leak

/**
 * Copyright (c) 2021 junfu0903@aliyun.com.
 *
 * Unpublished copyright. All rights reserved. This material contains
 * proprietary information that should be used or copied only within
 * junfu0903@aliyun.com, except with written permission of junfu0903@aliyun.com.
 *
 * @file mem_leak.c
 * @brief
 * @author junfu0903@aliyun.com
 * @version 1.0.0
 * @date 2021-06-15 10:57:19
 */

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
    char *p = (char*)malloc(16);
    p[0] = 1;

    return 0;
}
gcc -Wall -g -fsanitize=leak mem_leak.c -o mem_leak

在这里插入图片描述

开启Thread Sanitizer,将使代码执行效率降低2-20倍,内存使用增加5-10倍。可以通过设置-O1优化级别来提高内存利用率。

### 解决堆栈破坏检测导致程序终止的方法 当遇到 `stack smashing detected` 错误时,这通常意味着存在缓冲区溢出漏洞。为了修复此类问题并防止程序异常终止,可以采取以下措施: #### 1. 启用编译器保护机制 现代编译器提供了多种安全选项来帮助预防和检测堆栈溢出攻击。通过启用这些功能可以在一定程度上减少风险。 对于 GCC 编译器而言,在构建应用程序时应加入 `-fstack-protector-strong` 参数以增强防护力度[^1]: ```bash gcc -o myprogram source.c -fstack-protector-strong ``` #### 2. 使用静态分析工具查找潜在缺陷 利用诸如 AddressSanitizer 或 Valgrind 这样的内存调试工具可以帮助定位具体发生错误的位置以及原因所在。AddressSanitizer 是一种快速而有效的运行时检测手段,能够捕捉到非法访问等问题。 启动带有 ASan 的程序可以通过如下命令实现: ```bash gcc -fsanitize=address -g -o myprogram source.c ./myprogram ``` 如果确实存在问题,则会在终端输出详细的回溯信息以便进一步排查。 #### 3. 审查代码逻辑确保边界检查到位 仔细审查可能导致越界的数组操作部分,并引入必要的验证语句保证输入数据合法性。例如,在处理字符串复制之前先确认目标缓存空间充足再执行实际拷贝动作;或者采用更安全的标准库函数替代传统易受攻击版本(如使用 `strncpy()` 替代 `strcpy()`)。 另外值得注意的是,C++ 中推荐运用 STL 容器类代替原始指针管理方式因为前者自带范围安全性保障特性。 #### 4. 更新依赖项至最新稳定版 有时第三方库内部也可能潜藏安全隐患从而间接影响整个系统的稳定性。因此定期更新所使用的外部资源同样重要。 最后提醒开发者们养成良好的编程习惯——遵循最小权限原则分配变量作用域大小、及时释放不再需要的对象引用等良好实践均有助于降低遭遇类似情况的概率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sif_666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值