小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

splint

 Delores 2008-02-16

一.splint介紹

splint是一個動態(tài)檢查C語言程序安全弱點和編寫錯誤的程序.splint會進行
多種常規(guī)檢查,包括未使用的變量,類型不一致,使用未定義變量,無法執(zhí)行的
代碼,忽略返回值,執(zhí)行路徑未返回,無限循環(huán)等錯誤.

二.splint的安裝

1.rpm安裝

GTES 10.5和11版本已經(jīng)整合有splint軟件包,直接可以使用.

2.源代碼安裝

下載地址:
http://www./downloads/splint-3.1.2.src.tgz
源碼包安裝:
# tar zxvf splint-3.1.2.src.tgz
# cd splint-3.1.2
# ./configure
# make install

三.splint的使用

1.空引用錯誤

在引用沒有指向任何內(nèi)存地址的指針時,會導致這種錯誤.也就是使用了一個沒有賦值的指針.
splint支持一種特別的注釋.這種注釋寫在C程序代碼中,用于對程序進行特殊說明.
如下面這段程序.使用了/*@null@*/進行了說明,表示說明*s的值可能會是NULL.

//null.c
char firstChar1 (/*@null@*/ char *s)
{
return *s;
}
char firstChar2 (/*@null@*/ char *s)
{
if (s ==NULL) return '\0';
return *s;
}
//END

使用splint掃描這個程序時,會輸出:

# splint null.c
Splint 3.1.1 --- 28 Apr 2005
null.c: (in function firstChar1)
null.c:3:11: Dereference of possibly null pointer s: *s
null.c:1:35: Storage s may become null
Finished checking --- 1 code warning found
由于firstChar1和firstChar2都使用了null說明,表示指針s可能是個NULL值.
所以,splint會對s值的使用情況進行檢查.因為firstChar2函數(shù)中,對s的值進行
了NULL的判斷.所以,沒有對firstChar2函數(shù)的指針s輸出警告信息.

2.未定義的變量錯誤

C語言中,要求先定義變量,而后才可使用.所以,當使用一個沒有定義的變量時,編譯就會出錯.
如下例,使用/*@in@*/說明的變量,表示必須進行定義.使用/*@out@*/說明的變量,表示在 執(zhí)行過此函數(shù)后,這個變量就進行了定義.

// usedef.c
extern void setVal (/*@out@*/ int *x);
extern int getVal (/*@in@*/ int *x);
extern int mysteryVal (int *x);
int dumbfunc (/*@out@*/ int *x, int i)
{
if (i > 3) return *x;
else if (i > 1)
return getVal (x);
else if (i == 0)
return mysteryVal (x);
else
{
setVal (x);
return *x;
}
}
// END

使用splint檢查usedef.c

$ splint usedef.c
Splint 3.1.1 --- 28 Apr 2005
usedef.c: (in function dumbfunc)
usedef.c:7:19: Value *x used before definition
An rvalue is used that may not be initialized to a value on some execution
path. (Use -usedef to inhibit warning)
usedef.c:9:18: Passed storage x not completely defined (*x is undefined):
getVal (x)
Storage derivable from a parameter, return value or global is not defined.
Use /*@out@*/ to denote passed or returned storage which need not be defined.
(Use -compdef to inhibit warning)
usedef.c:11:22: Passed storage x not completely defined (*x is undefined):
mysteryVal (x)
Finished checking --- 3 code warnings
//錯誤原因: 由于程序中沒有對x進行定義,所以報未定義錯誤.但setVal()使用了/*@out@*/說明,所以
在setVal(x);和return x;中,沒有報未定義錯誤.

3.類型錯誤

C語言中的數(shù)據(jù)類型較多,各個之間有些細微差別.splint也可以對變量類型進行檢查.

示例1:

//bool.c
int f (int i, char *s,bool b1, bool b2)
{
if (i = 3) return b1;
if (!i || s) return i;
if (s) return 7;
if (b1 == b2)
return 3;
return 2;
}
//END

使用splint進行檢查:

$ splint bool.c
Splint 3.1.1 --- 28 Apr 2005
bool.c: (in function f)
bool.c:4:5: Test expression for if is assignment expression: i = 3
The condition test is an assignment expression. Probably, you mean to use ==
instead of =. If an assignment is intended, add an extra parentheses nesting
(e.g., if ((a = b)) ...) to suppress this message. (Use -predassign to
inhibit warning)
// 錯誤原因: if語句中的條件表達式是一個賦值語句.
bool.c:4:5: Test expression for if not boolean, type int: i = 3
Test expression type is not boolean or int. (Use -predboolint to inhibit
warning)
// 錯誤原因: if語句中的條件表達式的返回值,不是布爾型,而是整型.
bool.c:4:8: Return value type bool does not match declared type int: b1
Types are incompatible. (Use -type to inhibit warning)
// 錯誤原因: 返回值是布爾型,而不是整型.
bool.c:5:6: Operand of ! is non-boolean (int): !i
The operand of a boolean operator is not a boolean. Use +ptrnegate to allow !
to be used on pointers. (Use -boolops to inhibit warning)
// 錯誤原因: "!"操作符的操作數(shù)不是布爾型,而是整型i.
bool.c:5:11: Right operand of || is non-boolean (char *): !i || s
// 錯誤原因: "||"操作符的右操作數(shù)不是布爾型,而是字符指針.
bool.c:7:5: Use of == with boolean variables (risks inconsistency because of
multiple true values): b1 == b2
Two bool values are compared directly using a C primitive. This may produce
unexpected results since all non-zero values are considered true, so
different true values may not be equal. The file bool.h (included in
splint/lib) provides bool_equal for safe bool comparisons. (Use -boolcompare
to inhibit warning)
// 錯誤原因: 使用"=="對兩個布爾型進行比較.應該使用"&&".
Finished checking --- 6 code warnings

示例2:

//malloc1.c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *some_mem;
int size1=1048576;
some_mem=(char *)malloc(size1);
printf("Malloed 1M Memory!\n");
free(some_mem);
exit(EXIT_SUCCESS);
}
//END

使用splint檢查malloc1.c

$ splint malloc1.c
Splint 3.1.1 --- 28 Apr 2005
malloc1.c: (in function main)
malloc1.c:9:25: Function malloc expects arg 1 to be size_t gets int: size1
To allow arbitrary integral types to match any integral type, use
+matchanyintegral.
Finished checking --- 1 code warning

修改變量size1的定義為:

size_t size1=1048576;

再使用splint進行檢查.

$ splint malloc1.c
Splint 3.1.1 --- 28 Apr 2005
Finished checking --- no warnings

沒有檢查到錯誤.

4.內(nèi)存檢查

緩沖區(qū)溢出錯誤是一種非常危險的C語言錯誤,大部分安全漏洞都與它有關(guān).splint可以
對緩沖區(qū)的使用進行檢查.報告溢出或越界錯誤.
示例1:

//over.c
int main()
{
int buf[10];
buf[10] = 3;
retrun 0;
}
//END

使用splint進行檢查

$ splint over.c  +bounds +showconstraintlocation
Splint 3.1.1 --- 21 Apr 2006
Command Line: Setting +showconstraintlocation redundant with current value
over.c: (in function main)
over.c:6:3: Likely out-of-bounds store:
buf[10]
Unable to resolve constraint:
requires 9 >= 10
needed to satisfy precondition:
requires maxSet(buf @ over.c:6:3) >= 10
A memory write may write to an address beyond the allocated buffer. (Use
-likely-boundswrite to inhibit warning)
Finished checking --- 1 code warning

數(shù)組buf的大小是10字節(jié).最大可使用的元素位置為buf[9],但程序中使用了buf[10].
所以報錯.

示例2:

// bound.c
void updateEnv(char *str)
{
char *tmp;
tmp = getenv("MYENV");
if(tmp != NULL) strcpy(str,tmp);
}
void updateEnvSafe(char *str, size_t strSize)
{
char *tmp;
tmp = getenv("MYENV");
if(tmp != NULL)
{
strncpy(str, tmp, strSize -1);
str[strSize - 1] = '/0';
}
}
//END
$ splint bound.c +bounds +showconstraintlocation
Splint 3.1.1 --- 21 Apr 2006
Command Line: Setting +showconstraintlocation redundant with current value
bound.c: (in function updateEnv)
bound.c:6:19: Possible out-of-bounds store:
strcpy(str, tmp)
Unable to resolve constraint:
requires maxSet(str @ bound.c:6:26) >= maxRead(getenv("MYENV") @
bound.c:5:9)
needed to satisfy precondition:
requires maxSet(str @ bound.c:6:26) >= maxRead(tmp @ bound.c:6:30)
derived from strcpy precondition: requires maxSet(<parameter 1>) >=
maxRead(<parameter 2>)
A memory write may write to an address beyond the allocated buffer. (Use
-boundswrite to inhibit warning)
錯誤原因: 由于使用strcpy函數(shù)時,沒有指定復制字符串的長度,所以可能導致緩沖區(qū)
溢出.后面的updateEnvSafe函數(shù),使用了strncpy進行字符串復制,避免了這種情況.

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多