2016年3月9日 星期三

[Embedded] how to check heap corruption

上週的 linux news 提到 iOS 上的一個問題,Analysis of iOS & OS X Vulnerability: CVE-2016-1722,指出了 heap overflow 的問題。這篇新聞提醒了自己,應該要將之前的實戰經驗做一下整理了。本篇會針對如何找到 heap corruption 的方法作一整理。


為何會造成 heap corruption ? 主要可歸類為以下六種原因。

  • boundary overrun: a program writes beyond the malloc region.
  • boundary underrun: a program writes in front of the malloc region.
  • access to uninitialized memory: a program attempts to read memory that has not yet been initialized.
  • access to freed memory: a program attempts to read or write to memory that has been freed.
  • double frees: a program frees some structure that it had already freed. In such a case, a subsequent reference can pick up a meaningless pointer, causing a segmentation violation.
  • erroneous frees: a program calls free() on addresses that were not returned by malloc, such as static, global, or automatic variables, or other invalid expressions. See the malloc(3f) man page for more information.

針對不同原因,有不同的問題解決與判斷方法。以下將介紹幾種方法,可以找到造成 heap corruption 的原因。

1. 使用 cppcheck 先檢查明顯的程式碼錯誤
如果有錢的話,用 Parasoft C/C++test 或 klockwork 當然是更棒。

2. 使用 valgrind 工具
用法很簡單,例如:valgrind --leak-check=full  ./prog,只要你用的平台上有此工具,這是首選。但是在嵌入式系統上,有時候事情就是沒這麼完美。

3. 使用 Linux 提供的 mtrace() 工具
基本原理是替換四個函數 malloc(), realloc() memalign(), free(),並且將所有 malloc() free() 的過程都加以記錄。實際用法建議看官方手冊。可以用來找 memory leaks, double free 與 erroneous frees 的問題。

4.  使用環境變數 MALLOC_CHECK
若是不想重新編譯程式,要直接找到記憶體問題也是可以的,例如:執行 "env MALLOC_CHECK=1 ./prog",也可以達到與 mtrace() 同樣的功能。
5. 使用 strace
如果你運氣夠好,也許用 strace ./prog,會剛好讓你看到發生問題的點。
6. 使用 DUMA (Detect Unintended Memory Access)
此函數庫衍伸於" Electric Fence" ,可以用來發掘大多數的記憶體問題,若使用的作業系統上不支援上述工具,可能就得使用這個方式。
7, 使用 DMALLOC,可參考http://dmalloc.com

參考資料:
http://duma.sourceforge.net/
http://csweb.cs.wfu.edu/~torgerse/Kokua/More_SGI/007-2579-009/sgi_html/ch09.html
https://en.wikibooks.org/wiki/Linux_Applications_Debugging_Techniques/Leaks