Address Sanitizer

  ASAN最早可以追溯到 LLVM 的 sanitizers项目(https://github.com/google/sanitizers),这个项目包含了AddressSanitizer,MemorySanitizer,ThreadSanitizer 和 LeakSanitizer等工具。这些工具可以检测用户空间的内存问题。通过在编译时加入指定的选项,就可以给用户程序加入 Address Sanitizer 功能。

  其中Address Sanitizer(ASAN)工具是一个内存错误检测器,可以检测以下问题:

  1)Out-of-bounds accesses to heap, stack and globals 堆、栈以及全局变量越界

  2)Use-after-free 即访问dangling pointer,已经free的指针

  3)Use-after-return (to some extent)

  4)Double-free, invalid free

  5)Memory leaks (experimental)

  ASan基于shadow memory实现,目前已经集成到Clang 3.1和GCC 4.8以上版本。

编译选项

  -fsanitize=address 使能Address Sanitizer工具

   -fsanitize=leak 只使能Leak Sanitizer,检测内存泄漏问题

  -fno-omit-frame-pointer 检测到内存错误时打印函数调用栈

  -O1 代码优化选项,可以打印更清晰的函数调用栈

实例演示

1)栈溢出

#include <stdio.h>
#include <stdlib.h> int main(int argc, char **argv)
{
int stack[] = {}; stack[] = 0xdeadbeef; return ;
}

首先使用gcc stack-overflow.c -o stack-overflow编译,然后用./stack-overflow执行
linyao@chgao-virtual-machine:~/debugging/asan$ gcc stack-overflow.c -o stack-overflow
linyao@chgao-virtual-machine:~/debugging/asan$ ./stack-overflow
linyao@chgao-virtual-machine:~/debugging/asan$

程序没有任何报错,没有检测到栈越界。

接下来集成ASAN编译并执行,发现栈越界错误:

linyao@chgao-virtual-machine:~/debugging/asan$ gcc -fsanitize=address -fno-omit-frame-pointer stack-overflow.c -o stack-overflow
linyao@chgao-virtual-machine:~/debugging/asan$ ./stack-overflow
=================================================================
====ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffc6c0f67a0 at pc 0x0000004008fb bp 0x7ffc6c0f65d0 sp 0x7ffc6c0f65c0
WRITE of size at 0x7ffc6c0f67a0 thread T0
# 0x4008fa in main (/media/new/linyao/debugging/asan/stack-overflow+0x4008fa)
# 0x7fc449f7082f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.+0x2082f)
# 0x400748 in _start (/media/new/linyao/debugging/asan/stack-overflow+0x400748) Address 0x7ffc6c0f67a0 is located in stack of thread T0 at offset in frame
# 0x400825 in main (/media/new/linyao/debugging/asan/stack-overflow+0x400825) This frame has object(s):
[, ) 'stack' <== Memory access at offset overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow ??: main
Shadow bytes around the buggy address:
0x10000d816ca0:
0x10000d816cb0: f1 f1
0x10000d816cc0: f1 f1
0x10000d816cd0:
0x10000d816ce0:
=>0x10000d816cf0: [f4]f4 f3 f3 f3 f3
0x10000d816d00:
0x10000d816d10:
0x10000d816d20:
0x10000d816d30:
0x10000d816d40:
Shadow byte legend (one shadow byte represents application bytes):
Addressable:
Partially addressable:
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
====ABORTING

2)堆溢出

#include <stdio.h>
#include <stdlib.h> #define HEAP_SIZE (100) int main(int argc, char **argv)
{
int *heap = NULL; heap = (int *)malloc(HEAP_SIZE * sizeof(int));
if (NULL == heap)
return -; *(heap + HEAP_SIZE) = 0xdeadbeef; return ;
}

编译并执行:

linyao@chgao-virtual-machine:~/debugging/asan$ gcc -fsanitize=address -fno-omit-frame-pointer heap-overflow.c -o heap-overflow
linyao@chgao-virtual-machine:~/debugging/asan$ ./heap-overflow
=================================================================
====ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61400000ffd0 at pc 0x0000004007ab bp 0x7fffa2f87bd0 sp 0x7fffa2f87bc0
WRITE of size at 0x61400000ffd0 thread T0
# 0x4007aa in main (/media/new/linyao/debugging/asan/heap-overflow+0x4007aa)
# 0x7fc8239b682f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.+0x2082f)
# 0x400668 in _start (/media/new/linyao/debugging/asan/heap-overflow+0x400668) 0x61400000ffd0 is located bytes to the right of -byte region [0x61400000fe40,0x61400000ffd0)
allocated by thread T0 here:
# 0x7fc823df8602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.+0x98602)
# 0x400756 in main (/media/new/linyao/debugging/asan/heap-overflow+0x400756)
# 0x7fc8239b682f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.+0x2082f) SUMMARY: AddressSanitizer: heap-buffer-overflow ??: main
Shadow bytes around the buggy address:
0x0c287fff9fa0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff9fb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff9fc0: fa fa fa fa fa fa fa fa
0x0c287fff9fd0:
0x0c287fff9fe0:
=>0x0c287fff9ff0: [fa]fa fa fa fa fa
0x0c287fffa000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fffa010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fffa020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fffa030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fffa040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents application bytes):
Addressable:
Partially addressable:
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
====ABORTING

KASAN(Kernel Address Sanitizer)

  Andrey Ryabinin 借鉴了 AddressSanitizer 的思想,并在 Linux 内核中实现了 Kernel Address Sanitizer。所以 Kasan 也可以看成是用于内核空间的 Address Sanitizer。

  Kasan 是内核的一部分,使用时需要重新配置、编译并安装内核。Kasan 在 Linux 内核 4.0 版本时被引入内核,所以选择的内核代码需要高于 4.0 版本。另外,最基本的 Kasan 功能需要 GCC4.9.2 支持,更多的支持则需要 GCC5.0 及以上版本。

  Linux内核内存检查工具还有kmemcheck。另外,也可以通过使能SLAB_DEBUG/SLUB_DEBUG/DEBUG_SLAB/DEBUG_PAGEALLOC等内核配置选项监控内存使用情况。

Linux高级调试与优化——Address Sanitizer的更多相关文章

  1. Linux高级调试与优化——gdb调试命令

    番外 2019年7月26日至27日,公司邀请<软件调试>和<格蠹汇编——软件调试案例集锦>两本书的作者张银奎老师进行<Linux高级调试与优化>培训,有幸聆听张老师 ...

  2. Linux高级调试与优化——用户态堆

    内存问题是软件世界的住房问题 嵌入式Linux系统中,物理内存资源通常比较紧张,而不同的进程可能不停地分配和释放不同大小的内存,因此需要一套高效的内存管理机制. 内存管理可以分为三个层次,自底向上分别 ...

  3. Linux高级调试与优化——内存泄漏实战分析

    最近在整理Linux调试方面的文档,正好碰到了一个内存泄漏踩栈的问题,借此机会记录一下分析过程. 首先,发现问题之后,赶紧看一下产生coredump文件没有,果不其然,产生了coredump,果断上g ...

  4. Linux高级调试与优化——内存管理

    1.物理地址和虚拟地址 Linux采用页表机制管理内存,32位系统中页大小一般为4KB,物理内存被划分为连续的页,每一个页都有一个唯一的页号. 为了程序的的可移植性,进程往往需要运行在flat mem ...

  5. Linux高级调试与优化——信号量机制与应用程序崩溃

    背景介绍 Linux分为内核态和用户态,用户态通过系统调用(syscall)进入内核态执行. 用户空间的glibc库将Linux内核系统调用封装成GNU C Library库文件(兼容ANSI &am ...

  6. Linux高级调试与优化——同时抓取coredump和maps文件

    Linux内核源码 Documentation/sysctl/kernel.txt core_pattern: core_pattern: core_pattern is used to specif ...

  7. Linux高级调试与优化——ptrace

    ptrace (process trace) #include <sys/ptrace.h> long ptrace(enum __ptrace_request request, pid_ ...

  8. Linux高级调试与优化——进程管理和调度

    进程管理 进程和文件是Linux操作系统的两个最基本的抽象. 进程是处于执行期的程序,进程不仅仅局限于一段可执行程序代码,通常还包含其他资源,如打开的文件.挂起的信号.内核内部数据.处理器状态.进程地 ...

  9. Xcode 7 调试野指针利器 Address sanitizer

    Xcode 7 调试野指针利器 Address sanitizer 什么是Address Sanitizer? AddressSanitizer is a fast memory error dete ...

随机推荐

  1. NODE代理,yang

    const express = require('express'); const proxy = require('http-proxy-middleware');//引入代理中间件 const a ...

  2. angular装饰器

    @NgModule 元数据 NgModule 是一个带有 @NgModule() 装饰器的类.@NgModule() 装饰器是一个函数,它接受一个元数据对象,该对象的属性用来描述这个模块.其中最重要的 ...

  3. 第八篇 CSS定位

    CSS定位 CSS除了内外边距控制元素,还有定位,看到“定位”两个字,同学们应该就能清楚,它能够做什么.   在刚学习的时候,我也经常使用定位,来控制元素的位置,但是初学的同学可能会注意不到定位的一些 ...

  4. Array.reduce()方法

    Array.reduce()方法是对数组的遍历,返回一个单个返回值   使用方法: Array.reduce((acc, cur, idx, src) => { }, initialValue) ...

  5. dumpe2fs Linux支持的文件系统

    dumpe2fs  (-bh)装置文件名 选项与参数: -b : 列出保留为坏轨的部分 -h : 仅列出superblock的数据,不会列出其他的区段内容 查看Linux支持的文件系统哪些支持: ls ...

  6. springboot集成dubbo服务报错No provider available for the service

    检查了下发现是因为没有正确编写暴露服务的注解,需要注意下: @Service(interfaceClass = StudentService.) @Component public class Stu ...

  7. ftp上传下载功能实现

    该程序分为客户端和服务端,目前已经实现以下功能: 1. 多用户同时登陆 2. 用户登陆,加密认证 3. 上传/下载文件,保证文件一致性 4. 传输过程中现实进度条 5. 不同用户家目录不同,且只能访问 ...

  8. yield from语法

    yield from 是在Python3.3才出现的语法.所以这个特性在Python2中是没有的. yield from 后面需要加的是可迭代对象,它可以是普通的可迭代对象,也可以是迭代器,甚至是生成 ...

  9. Android 腾讯bugly Tinker 热修复

    Bugly热更新是腾讯推出的热更新框架,热更新是指无需到应用市场重新下载安装app,只需要在app内下载补丁包即可实现app的更新,主要用于app的bug修复或者少量改动. 大家在使用app(特别是游 ...

  10. LINUX学习之一基础篇

    1.计算机硬件五大单元:运算器.控制器.存储器.I/O设备 2.CPU种类:精简指令集(RISC)和复杂指令集(CISC) 3.1Byte=8bit,扇区大小为512bytes 4.芯片组通常分为两个 ...