Splint介紹


1. 靜態分析工具 VS 編譯器

      編譯器負責把C源程序快速、高效地轉變為可執行文件,不對代碼做類型檢查(特別是對分別編譯的程序),有益於做到快速與高效。

      Lint沒有“高效”的要求,可以花更多時間對代碼進行更深入、仔細的檢查。

2. C代碼靜態分析工具

Its4

讀取一個或多個 C/C++源程序,將每個源程序分割成函數標志流,然后檢查生成的標志是否存在於漏洞數據庫中,從而得到每個源程序的所有錯誤警告列表,並帶有相關的描 述。其規則庫vulns.i4d定義了各種函數的危險等級,描述等,通過規則匹配來報出風險,但它不能理解程序上下文意思,存在很大的誤報。

Flawfinder

詞法掃描和分析,內嵌了一些漏洞數據庫,如緩沖區溢出、格式化串漏洞等,掃描快,按照代碼中漏洞的風險等級對漏洞進行划分,可以快速找到存在的問題,誤報較高。

Rats

掃描C、C++、Perl、PHP和Python開發的源程序中潛在的漏洞,掃描規則比較粗糙。

PC-lint

一個由Gimpel Software提供的支持C/C++的商用程序

Splint

(原來的 LCLint) 是一個GNU免費授權的 Lint程序,是一個動態檢查C語言程序安全弱點和編寫錯誤的程序。Splint會進行多種常規檢查,包括未使用的變量,類型不一致,使用未定義變量,無法執行的代碼,忽略返回值,執行路徑未返回,無限循環等錯誤。

3. splint安裝

./configure  --prefix=$HOME/splint

make make install

4. 配置

•#vi  ~/.bashrc
在文件中加入:
export LARCH_PATH=$HOME/splint/share/splint/lib
export LCLIMPORTDIR=$HOME/splint/share/splint/imports
.  ~/.bashrc
環境變量export PATH=$HOME/splint/bin:$PATH
 
5. 檢查控制

splint提供了三種方式進行檢查的控制,分別是flags標志、 .splintrc配置文件和格式化注釋。

 

•flags: splint支持幾百個標志用來控制檢查和消息報告,使用時標志前加‘+’或‘-’,‘+’標志開啟這個標志,‘-’表示關閉此標志。下面例子展示了flags標志的用法:

      splint -showcol a.c //在檢測a.c時,告警消息中列數不被打印
splint -varuse a.c //在檢測a.c時,告警消息中未使用變量告警不被打印

 

•.splintrc配置文件: .splintrc文件中對一些flags做了默認的設定,命令行中指定的flags會覆蓋.splintrc文件中的標志。

 

格式化注釋:格式化注釋提供一個類型、變量或函數的額外的信息,可以控制標志設置,增加檢查效果。所有格式化注釋都以/*@開始,@*/結束,比如在函數參數前加 /*@null@*/,表示該參數可能是NULL,做檢測時,splint會加強對該參數的值的檢測。
 
6.
•在$HOME目錄下新增.splintrc文件

  -sysdirs /usr/include/:/usr/include/netinet/:/home/gaps/libevent/include/:/home/gaps/libsrc/hslib/common/:/home/gaps/libsrc/gaps/libsha/libincl:/home/gaps/libsrc/dci/include:/home/gaps/libsrc/hslib/libsxml:/home/gaps/src/mcmi/mcmi_cli:/home/gaps/libsrc/gaps/libgapssql:/home/gaps/libsrc/gaps/libgapssfs/libincl

         +single-include

         +skipsysheaders

          +unixlib +bounds

         -I/usr/include-I/home/gaps/incl

         -I/home/gaps/libevent/include

         -I/home/gaps/libincl

         -I/home/gaps/libsrc/dci/include

         -I/home/gaps/libsrc/gaps/libgapssfs/libincl

         -I/home/gaps/libsrc/gaps/libgapssql

         -I/home/gaps/libsrc/gaps/libsha/libincl -I/home/gaps/libsrc/hslib/common

         -I/home/gaps/libsrc/hslib/libsxml -I/home/gaps/lua/include- I/home/gaps/sqlite/include

        -I/home/gaps/src/mcmi/mcmi_cli -I/home/gaps/src/mcmi/memcached
 
7.
Splint的unixlib包括posixlib包括isolib。但都不包含<limits.h>定義的UINT_MAX等宏
Splint的unixlib比posixlib多了(如果用posixlib,自己寫的這幾個同名頭文件似乎就不會被splint include進去?checking macros階段看出來用上了?):
[1]<unistd.h>定義的socklen_t,in_addr_t,sa_family_t等類型
[2]<sys/select.h>定義的fd_set類型和select函數(遵循POSIX 1003.1-2001)。
[3]<pthread.h>定義的pthread_t,pthread_mutex_t等類型。但卻有pthread_create等函數聲明。
怎樣查看splint的posixlib庫包含了哪些頭文件?
Splint 知道的POSIX規格是IEEE 1003.1-1990,所以不支持之后規格(如IEEE Std 1003.1b-1993)導入的特性,如siginfo_t結構體等。有兩個辦法解決:[1]干凈的辦法是,更新posix.h后重新生成 posix.lcd和posixstric.lcd。Splint手冊第14.2節講述了這方面內容:splint 源碼包的lib目錄下就有 standard/posix/unix三個庫的頭文件和lcd文件。按照指示生成一個lcd文件后,在之后運行splint檢查時以“-load”選項加載一個自己創建的lcd(注意:最多只能加載一個自己創建的lcd)。[2]As a quick-and-dirty solution, you could provide a dummy definition for siginfo_t.
(4)自己工程定義的宏沒有設置好導致語法錯誤。
 
8.

有些數據類型或函數是編譯器擴展的,例如上面的/usr/include/bits/sigthread.h的33行的__sigset_t應當用sigset_t代替:

  sigemptyset((__sigset_t *)&sa.sa_mask);
9.

GCC編譯器內建的數據類型__built_va_list被GCC作為基本類型了。

所以,Splint手冊指出系統頭文件一般是不可解析的!要處理GCC所有內建的預處理宏、數據結構、函數很難,Splint郵件列表有人嘗試以這種方式lint linux內核模塊成功了。

可能自編C文件依賴於include的系統頭文件中某些擴展宏、數據結構、函數聲明,可以自己編寫與之同名的頭文件。這個很容易的:不需要修改工程中任何文件,並且一般寫兩三個很短的頭文件就行了。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM