源码基于:OH4.0

0. 前言

相对于 Android 中的 Asan 和 HWAsan,鸿蒙中也配套有 sanitizer 用于内存异常检测。

1. OH BUILD.gn 可配置

ohos_shared_library("example") {
  sanitize = {
    cfi = true                             # 开启控制流完整性检测
    cfi_cross_dso = true                   # 开启跨so调用的控制流完整性检测
    integer_overflow = true                # 开启整数溢出检测
    boundary_sanitize = true               # 开启边界检测
    ubsan = true                           # 开启部分ubsan选项
    all_ubsan = true                       # 开启全量ubsan选项
    debug = true                           # 可选,调测模式,默认是不开启
    blocklist = "./blocklist.txt"          # 可选,屏蔽名单路径
  }
  ...
}

1.1 支持的Sanitizer类型

目前支持开启的Sanitizer:

  • 整数溢出排错:unsigned_integer_overflow/signed_integer_overflow/integer_overflow(同时包括无符号和有符号整数溢出两种检查)
  • 控制流完整性:cfi、cfi_cross_dso(跨so的cfi检查)
  • 边界检测:boundary_sanitize
  • 部分未定义行为检测:ubsan(bool,integer-divide-by-zero,return,returns-nonnull-attribute,shift-exponent,unreachable,vla-bound等编译选项)
  • 全量未定义行为检测:all_ubsan(全量undefined behavior sanitizer编译选项)

1.2 发布、调测模式

通过debug选项控制使用发布模式还是调测模式,默认为发布模式,使用debug = true显式声明开启调测模式。debug选项仅对Sanitizer生效,且与模块是否编译为调试版本无关,但在模块发布版本的编译配置中不应带此选项,或显式地将debug设置为false,使得Sanitizer处于发布模式。

  • 调测模式:用于开发时排查问题。该模式下会输出产生错误相关的丰富信息来辅助定位错误,并且在发生错误后并不会直接中断程序运行,而是会恢复程序运行进一步识别后续的错误。

  • 发布模式:保护程序不发生错误或被恶意攻击,在产生错误后直接中断程序不会继续执行。

1.3 屏蔽名单

指定该模块中不受Sanitizer选项影响的函数或源程序文件名单,用于避免良性行为被识别为错误、热点函数产生了不合理、不可接受的开销;该名单需谨慎使用。名单示例如下所示:

[cfi]
fun:*([Tt]est|TEST)*
fun: main
 
[integer]
src:example/*.cpp

2. sanitizer 的config配置文件

OH sanitize 编译的config 配置文件:

build/config/sanitizers/BUILD.gn

build/config/sanitizers/sanitizers.gni

3. 示例

3.1 OOB 1

示例代码:

int test_func_oob() {
    int a[5] = {0};

    printf("a[5]: %d\n", a[5]);

    return 0;
}

异常log: 

../../device/soc/shift/jr510/hardware/demo/asan_test.c:12:26: runtime error: index 5 out of bounds for type 'int[5]'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../../device/soc/shift/jr510/hardware/demo/asan_test.c:12:26 in
../../device/soc/shift/jr510/hardware/demo/asan_test.c:12:26: runtime error: load of address 0x007fc6c9903c with insufficient space for an object of type 'int'
0x007fc6c9903c: note: pointer points here
  00 00 00 00 00 00 00 00  50 90 c9 c6 7f 00 00 00  34 1a 00 8b 7f 00 00 00  a0 90 c9 c6 7f 00 00 00
              ^
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../../device/soc/shift/jr510/hardware/demo/asan_test.c:12:26 in

 

3.2 OOB 2

示例代码:

int g_abc[11];
int test_func_global_overflow() {
    int i = 0;

    for(i = 0; i < 100; ++i) {
        printf("value:%d \t", g_abc[i]);
        if (i%10 ==0 && i != 0) {
            printf("\n");
        }
    }

    return g_abc[12];
}

异常log:

../../device/soc/shift/jr510/hardware/demo/asan_test.c:46:31: runtime error: index 11 out of bounds for type 'int[11]'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../../device/soc/shift/jr510/hardware/demo/asan_test.c:46:31 in 

其实使用OH sanitize 配置,可检测的异常不多,好在除了这些,还可以通过编译参数进行进一步的检测。 

3.3 UAF

示例代码: 

int test_func_uaf() {
    char *x = (char*)malloc(10 * sizeof(char*));
    free(x);

    printf("x[5]: %c\n", x[5]);

    return 0;
}

异常log:

=================================================================
==23916==ERROR: AddressSanitizer: heap-use-after-free on address 0x0063b3fe0c25 at pc 0x0055860c65a4 bp 0x007fdcaf1080 sp 0x007fdcaf1078
READ of size 1 at 0x0063b3fe0c25 thread T0
    #0 0x55860c65a0  (/vendor/bin/asan_test+0xc55a0)
    #1 0x7fb4f7ba30  (/lib/ld-musl-aarch64.so.1+0x7ca30)
    #2 0x55860c6534  (/vendor/bin/asan_test+0xc5534)
 
0x0063b3fe0c25 is located 5 bytes inside of 80-byte region [0x0063b3fe0c20,0x0063b3fe0c70)
freed by thread T0 here:
    #0 0x558609d874  (/vendor/bin/asan_test+0x9c874)
    #1 0x55860c655c  (/vendor/bin/asan_test+0xc555c)
    #2 0x7fb4f7ba30  (/lib/ld-musl-aarch64.so.1+0x7ca30)
    #3 0x55860c6534  (/vendor/bin/asan_test+0xc5534)
 
previously allocated by thread T0 here:
    #0 0x558609d99c  (/vendor/bin/asan_test+0x9c99c)
    #1 0x55860c6554  (/vendor/bin/asan_test+0xc5554)
    #2 0x7fb4f7ba30  (/lib/ld-musl-aarch64.so.1+0x7ca30)
    #3 0x55860c6534  (/vendor/bin/asan_test+0xc5534)
...

BUILD.gn 配置如下:

ohos_executable("asan_test") {
  sources = [
    "./asan_test.c"
  ]
 
  cflags = [
    "-Wno-array-bounds",
    "-Wno-unused",
    "-fsanitize=address",
    "-fno-omit-frame-pointer",
  ]
 
  ldflags = [
    "-fsanitize=address",
    "-fno-omit-frame-pointer",
  ]

3.4 global-buffer-overflow

示例代码:

int g_abc[11];
int test_func_global_overflow() {
    int i = 0;

    for(i = 0; i < 100; ++i) {
        printf("value:%d \t", g_abc[i]);
        if (i%10 ==0 && i != 0) {
            printf("\n");
        }
    }

    return g_abc[12];
}

该用例同第 3.2 节,不过这里是利用  "-fsanitize=address" 进行编译,log 会详细些。

异常log:

=================================================================
==10349==ERROR: AddressSanitizer: global-buffer-overflow on address 0x00558334674c at pc 0x00558310e6bc bp 0x007fe275e330 sp 0x007fe275e328
READ of size 4 at 0x00558334674c thread T0
    #0 0x558310e6b8  (/vendor/bin/asan_test+0xc56b8)
    #1 0x7f92bfba30  (/lib/ld-musl-aarch64.so.1+0x7ca30)
    #2 0x558310e5e4  (/vendor/bin/asan_test+0xc55e4)

0x00558334674c is located 0 bytes to the right of global variable 'g_abc' defined in '../../device/soc/shift/jr510/hardware/demo/asan_test.c' (0x5583346720) of size 44
SUMMARY: AddressSanitizer: global-buffer-overflow (/vendor/bin/asan_test+0xc56b8) 
Shadow bytes around the buggy address:
  0x001ab0668c90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001ab0668ca0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001ab0668cb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001ab0668cc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001ab0668cd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x001ab0668ce0: 00 00 00 00 00 00 00 00 00[04]f9 f9 f9 f9 f9 f9
  0x001ab0668cf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001ab0668d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001ab0668d10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001ab0668d20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001ab0668d30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

...

 

参考:

https://justinwei.blog.csdn.net/article/details/131322020 

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐