自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何利用Sanitizer解決Android中的Bug?

企業(yè)動態(tài)
本文將詳細介紹現(xiàn)有 Android 擦除器(AddressSanitizer、UndefinedBehaviorSanitizer 和 SanitizerCoverage)的內部結構,并演示可以如何在 Android 構建系統(tǒng)中使用它們。

LLVM 是構建 Android 所使用的編譯器基礎架構,包含多個用于執(zhí)行靜態(tài)和動態(tài)分析的組件。在分析 Android 時,得到廣泛使用的一組組件是擦除器,特別是 AddressSanitizer、UndefinedBehaviorSanitizer 和 SanitizerCoverage。

這些擦除器是包含在 compiler-rt 中的基于編譯器的儀器測試組件,可在開發(fā)和測試過程中用于消除錯誤和優(yōu)化 Android。Android 中當前提供的這些擦除器可以發(fā)現(xiàn)和診斷多種內存濫用錯誤和未定義的行為,還可以提供代碼覆蓋指標,確保您的測試套件盡可能面面俱到。

本文將詳細介紹現(xiàn)有 Android 擦除器(AddressSanitizer、UndefinedBehaviorSanitizer 和 SanitizerCoverage)的內部結構,并演示可以如何在 Android 構建系統(tǒng)中使用它們。

Address Sanitizer

AddressSanitizer (ASan) 是一項基于編譯器的儀器測試功能,可在運行時檢測 C/C++ 代碼中的多種內存錯誤。在 Android 中,已經測試了對下列內存錯誤類型的檢查功能:

  • 堆、堆疊和全局變量的越界訪問
  • 釋放后使用
  • 返回后使用(運行時標志 ASAN_OPTIONS=detect_stack_use_after_return=1)
  • 范圍后使用(clang 標志 -fsanitize-address-use-after-scope)
  • 重復釋放,無效釋放

Android 可通過 ASan 執(zhí)行全面的構建儀器測試,還可以通過 asanwrapper 執(zhí)行應用級的 ASan 儀器測試。關于這兩種儀器測試技巧的說明均可在 source.android.com 中找到。

AddressSanitizer 基于以下兩個高級概念。***個概念是針對與內存有關的所有函數調用(包括 alloca、malloc 和 free 等)執(zhí)行儀器測試并輸出用于跟蹤內存分配、釋放和使用情況統(tǒng)計的信息。通過此儀器測試,ASan 可檢測無效的內存使用錯誤,包括重復釋放、范圍后使用、返回后使用和釋放后使用等錯誤。ASan 還可以檢測在定義的內存區(qū)域邊界外發(fā)生的讀寫操作。為完成此檢測,它填充所有分配的內存緩沖區(qū)和變量。如果對此填充區(qū)域進行讀或寫,ASan 將捕獲此操作,并輸出有助于診斷內存違例的信息。在 ASan 術語中,此填充被稱為中毒內存。

下面是包含堆疊分配變量的中毒內存填充布局示例:

包含堆疊分配變量的中毒內存填充布局示例

上圖是ASANified 堆疊變量示例,此變量包含一個由 8 個元素組成的 int8_t 數組、一個 uint32_t 數組和一個由 16 個元素組成的 int8_t 數組。右側顯示使用 ASAN 編譯后的內存布局,其中每個變量之間插入填充。對于每個堆棧變量,變量前后有 32 個填充字節(jié)。如果一個變量的對象大小不是 32 個字節(jié),則插入 32 - n 個額外的填充字節(jié),其中 n 是對象大小。

ASan 使用影子內存跟蹤哪些字節(jié)為正常內存,哪些字節(jié)為中毒內存。字節(jié)可以標記為完全正常(在影子內存中標記為 0)、完全中毒(設置對應影子字節(jié)的高位)或前面 k 個字節(jié)未中毒(影子字節(jié)值為 k)。如果影子內存顯示某個字節(jié)中毒,則 ASan 會使程序崩潰,并輸出有用的調試信息,包括調用堆棧、影子內存映射、內存違例類型、讀取或寫入的內容、導致違例的計算機以及內存內容。

  1. AddressSanitizer: heap-buffer-overflow on address 0xe6146cf3 at pc 0xe86eeb3c bp 0xffe67348 sp 0xffe66f14 
  2. WRITE of size 39 at 0xe6146cf3 thread T0 
  3.     #0 0xe86eeb3b  (/system/lib/libclang_rt.asan-arm-android.so+0x64b3b) 
  4.     #1 0xaddc5d27  (/data/simple_test_fuzzer+0x4d27) 
  5.     #2 0xaddd08b9  (/data/simple_test_fuzzer+0xf8b9) 
  6.     #3 0xaddd0a97  (/data/simple_test_fuzzer+0xfa97) 
  7.     #4 0xaddd0fbb  (/data/simple_test_fuzzer+0xffbb) 
  8.     #5 0xaddd109f  (/data/simple_test_fuzzer+0x1009f) 
  9.     #6 0xaddcbfb9  (/data/simple_test_fuzzer+0xafb9) 
  10.     #7 0xaddc9ceb  (/data/simple_test_fuzzer+0x8ceb) 
  11.     #8 0xe8655635  (/system/lib/libc.so+0x7a635) 
  12. 0xe6146cf3 is located 0 bytes to the right of 35-byte region [0xe6146cd0,0xe6146cf3) 
  13. allocated by thread T0 here: 
  14.     #0 0xe87159df  (/system/lib/libclang_rt.asan-arm-android.so+0x8b9df) 
  15.     #1 0xaddc5ca7  (/data/simple_test_fuzzer+0x4ca7) 
  16.     #2 0xaddd08b9  (/data/simple_test_fuzzer+0xf8b9) 
  17. SUMMARY: AddressSanitizer: heap-buffer-overflow (/system/lib/libclang_rt.asan-arm-android.so+0x64b3b)  
  18. Shadow bytes around the buggy address: 
  19.   0x1cc28d40: fa fa 00 00 00 00 07 fa fa fa fd fd fd fd fd fd 
  20.   0x1cc28d50: fa fa 00 00 00 00 07 fa fa fa fd fd fd fd fd fd 
  21.   0x1cc28d60: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fd 
  22.   0x1cc28d70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
  23.   0x1cc28d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
  24. =>0x1cc28d90: fa fa fa fa fa fa fa fa fa fa 00 00 00 00[03]fa 
  25.   0x1cc28da0: fa fa 00 00 00 00 07 fa fa fa 00 00 00 00 03 fa 
  26.   0x1cc28db0: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa 
  27.   0x1cc28dc0: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fd 
  28.   0x1cc28dd0: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fd 
  29.   0x1cc28de0: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fd 
  30. Shadow byte legend (one shadow byte represents 8 application bytes): 
  31.   Addressable:           00 
  32.   Partially addressable: 01 02 03 04 05 06 07  
  33.   Heap left redzone:       fa 
  34.   Freed heap region:       fd 
  35.   Stack left redzone:      f1 
  36.   Stack mid redzone:       f2 
  37.   Stack right redzone:     f3 
  38.   Stack after return:      f5 
  39.   Stack use after scope:   f8 
  40.   Global redzone:          f9 
  41.   Global init order:       f6 
  42.   Poisoned by user:        f7 
  43.   Container overflow:      fc 
  44.   Array cookie:            ac 
  45.   Intra object redzone:    bb 
  46.   ASan internal:           fe 
  47.   Left alloca redzone:     ca 
  48.   Right alloca redzone:    cb 

有關報告各個部分的含義以及如何提高其易讀性的更多信息,可查看 LLVM 網站:

https://clang.llvm.org/docs/AddressSanitizer.html

和 Github:

https://github.com/google/sanitizers/wiki/AddressSanitizer

有時,錯誤發(fā)現(xiàn)過程可能無法確定問題所在,當錯誤需要特殊設置或更高級的技巧(例如堆填充或利用爭用條件)才能發(fā)現(xiàn)時,更是如此。其中許多錯誤并不能即時發(fā)現(xiàn),可能需要檢查數千條指令才能找到內存違例的真正原因所在。ASan 可針對所有與內存有關的函數執(zhí)行儀器測試并為必須觸發(fā) ASan 相關回調才可訪問的區(qū)域填充數據,可在發(fā)生內存違例時立即捕獲違例,而不是等待崩潰導致數據損壞。這對于錯誤發(fā)現(xiàn)和根源診斷極為有用。此外,ASAN 還是一個非常有用的模糊測試工具,一直用于 Android 上的各種模糊測試工作。

UBSan

UndefinedBehaviorSanitizer (UBSan) 執(zhí)行編譯時儀器測試,檢查各種未定義的行為。設備制造商可通過將 LOCAL_SANITIZE:=default-ub 包含到生成文件或將 default-ub: true 包含到 blueprint 文件的 sanitize 塊中,將 UBSan 加入其測試構建中。UBSan 可以檢測多種未定義的行為,而 Android 的構建系統(tǒng)直接支持:

  • bool
  • integer-divide-by-zero
  • return
  • returns-nonnull-attribute
  • shift-exponent
  • unreachable
  • vla-bound

Android 的構建系統(tǒng)還使用了 UBSan 的整數溢出檢查功能。UBSan 還支持 unsigned-integer-overflow,這不是嚴格意義上的未定義行為,但它包含在擦除器中。在生成文件中,可以將 LOCAL_SANITIZE 設置為 signed-integer-overflow、unsigned-integer-overflow 或 combination flag integer,啟用 signed-integer-overflow、unsigned-integer-overflow、integer-divide-by-zero、shift-base 和 shift-exponent,以啟用這些行為。在 blueprint 文件中,可以將 Misc_undefined 設置為所需的標志,啟用這些行為。這些 UBSan 目標,尤其是 unsigned-integer-overflow,廣泛用于 mediaserver 組件中,以用來消除任何潛在的整數溢出漏洞。

在 Android 中,當出現(xiàn)未定義的行為時,默認的做法是中止程序。但是,從 2016 年 10 月開始,Android 中的 UBSan 將提供一個可選的運行時庫,其報告的錯誤信息將更加詳細,包括出現(xiàn)的未定義行為類型、文件和源代碼行信息。

在 Android.mk 文件中,可通過以下方式啟用該庫:

  1. LOCAL_SANITIZE:=unsigned-integer-overflow signed-integer-overflow 
  2. LOCAL_SANITIZE_DIAG:=unsigned-integer-overflow signed-integer-overflow 

而在 Android.bp 文件中,可通過以下方式啟用該庫:

  1. sanitize: { 
  2.         misc_undefined: [ 
  3.             "unsigned-integer-overflow", 
  4.             "signed-integer-overflow", 
  5.         ], 
  6.         diag: { 
  7.             misc_undefined: [ 
  8.                 "unsigned-integer-overflow", 
  9.                 "signed-integer-overflow", 
  10.             ], 
  11.         }, 
  12.     }, 

下面是 UBSan 運行時庫提供的信息示例:

  1. external/icu/icu4c/source/common/ucnv.c:1193:23: runtime error: unsigned integer overflow: 4291925010 + 2147483647 cannot be represented in type 'unsigned int' 
  2. external/icu/icu4c/source/common/cstring.c:288:16: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'uint32_t' (aka 'unsigned int') 
  3. external/harfbuzz_ng/src/hb-private.hh:894:16: runtime error: unsigned integer overflow: 72 - 55296 cannot be represented in type 'unsigned int' 
  4. external/harfbuzz_ng/src/hb-set-private.hh:82:24: runtime error: unsigned integer overflow: 32 - 562949953421312 cannot be represented in type 'unsigned long' 
  5. system/keymaster/authorization_set.cpp:500:37: runtime error: unsigned integer overflow: 6843601868186924302 * 24 cannot be represented in type 'unsigned long' 

SanitizerCoverage

Sanitizer 工具內置一個非常簡單的代碼覆蓋工具。SanitizerCoverage 可實現(xiàn)調用級、基本塊級和邊緣級的代碼覆蓋。此 Sanitizer 可用作獨立的儀器測試工具,也可與其他任何擦除器配合使用,包括 AddressSanitizer 和 UndefinedBehaviorSanitizer 等。要使用這一基于 Guard 的新覆蓋工具,請設置 fsanitize-coverage=trace-pc-guard。編譯器將在每個邊緣插入 __sanitizer_cov_trace_pc_guard(&guard_variable)。每個邊緣均有各自的 uint32_t guard_variable。

此外,還會生成模塊構造函數,即 __sanitizer_cov_trace_pc_guard_init(uint32_t* start, uint32_t* stop)。所有 __sanitizer_cov_ 函數均應由用戶提供。您可以按照使用 Guard 跟蹤計算機中的示例操作:

https://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards

除了跟蹤控制流外,SanitizerCoverage 還可以跟蹤數據流。此功能可通過 fsanitize-coverage=trace-cmp 激活,并通過 __sanitizer_cov_trace_* 函數檢測所有開關和比較指令來實現(xiàn)。對于整數除法和 GEP 指令,也存在類似的功能,可分別通過 fsanitize-coverage=trace-div 和 fsanitize-coverage=trace-gep 激活。這是一個實驗性界面,可能危及線程安全,可能隨時更改,但在 Android 構建中提供并可運行此界面。

在擦除器覆蓋會話期間,覆蓋信息記錄在兩個文件中,即 .sancov 文件和 sancov.map 文件。前一個文件包含程序的所有儀器測試點,而后一個文件包含在前一個文件中用一系列索引表示的執(zhí)行跟蹤。默認情況下,這兩個文件存儲在當前工作目錄中,系統(tǒng)將為執(zhí)行過程中運行的每個可執(zhí)行的共享對象創(chuàng)建一個目錄。

結論

 

ASan、UBSan 和 SanitizerCoverage 僅僅是 LLVM 擦除器在 Android 中應用的開端。目前,正在向 Android 構建系統(tǒng)中集成更多的 LLVM 擦除器。本文所介紹的擦除器可用作代碼運行狀況和系統(tǒng)穩(wěn)定性檢測工具,Android 安全團隊甚至正在用它們來發(fā)現(xiàn)和預防安全錯誤!

【本文是51CTO專欄機構“谷歌開發(fā)者”的原創(chuàng)稿件,轉載請聯(lián)系原作者(微信公眾號:Google_Developers)】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2021-10-14 07:49:32

SanitizerDOM消毒

2011-02-25 16:55:58

Android

2021-01-13 10:53:48

人工智能費用管理AI

2014-05-22 10:54:27

iOS開發(fā)查找BUG

2019-08-26 08:58:41

程序員Bug開發(fā)

2019-11-14 11:05:32

ARP命令故障

2024-01-02 13:16:00

數據遷移PythonPETL

2009-03-18 08:59:28

throw異常Java

2011-07-28 14:45:36

XCode 調試 BUG

2016-02-29 10:01:59

iosbug合理

2010-02-23 14:56:18

WCF Bug

2024-03-07 13:35:44

數字鴻溝智慧城市人工智能

2021-10-14 13:14:12

安全供應鏈漏洞威脅

2010-02-05 15:09:50

2015-04-06 16:42:16

BugTimsort算法玉兔月球車

2015-11-17 09:37:52

網頁設計黃金比例

2017-10-10 15:14:23

BUGiOS 11蘋果

2015-07-30 11:36:48

Xcode7ClangAddress San

2021-04-06 11:18:26

云計算SD-WAN云安全

2014-05-22 16:32:48

bug查找bug
點贊
收藏

51CTO技術棧公眾號