Tool name:Coverityhtml
Brief introduction about Coverity:linux
Prevent SQS(軟件質量系統)是檢測和解決C、C++、Java源代碼中最嚴重的缺陷的領先的自動化方法。經過對您的構建環境、源代碼和開發過程給出一個完整的分析,Prevent SQS創建了得到高質量軟件的標準。express
靜態源代碼分析容許咱們再軟件開發生命週期的早期階段發現和修復缺陷,節省數以百萬計的相關成本。Prevent SQS是業界標準,由於只有Coverity理解和掌握靜態源代碼分析技術所具備的嚴格的要求。安全
Common Issue and Solutions:ide
1.Buffer not null terminated(緩衝區不以null終止)oop
example:ui
void buffer_size_example() { static char source[] = "Twenty characters!!!"; char dest[10]; strncpy(dest, source, strlen(dest)); //或者strncpy(dest, source, //strlen(source)); 直接致使棧溢出。 }
problem:spa
In the above example, a call to strncpy()
generates an error because the length of the source string is twenty characters, but the destination string can only have a maximum of 10 characters:scala
Solution:rest
通常狀況下,使用strncpy時,建議將n置爲dest串長度,複製完畢後,爲保險起見,將 dest串最後一字符置NULL,避免發輸出亂碼問題。固然嘍,不管是strcpy仍是strncpy,保證 src串長度<dest串長度纔是最重要的。
2.String not null terminated(字符串不以null結尾)
example:
char *string_null_example() { char name[1024]; char *extension; string_from_net(fd, 1023, name); // read from net, no null-termination if (x[0] != SOME_CHAR) { extension = process_filename(name); // process until '\0' found } }
problem:
This example reports a defect because the name
string is not null- terminated and is passed to process_filename()
, which searches name
until it finds a null terminator. If name
lacks a null-terminator process_filename()
could potentially corrupt memory.
Solution:
A quick fix for these type of defects is to null-terminate strings after reading them in from a string null source such as string_from_net()
and before passing them to a string null sink such as process_filename()
.
3.Overflowed return value(返回值溢出)
example:
#include <unistd.h> #define INT_MAX 2147483647 class Cell { public: int a; int *b; }; void test(int x, int fd) { int y; read(fd, &y, 4); // y is from a tainted (outside) source int size = y; Cell *mycell; if (size != 0) { // Overflow results from operation size * sizeof(Cell) // Overflowed value is used in memory allocation mycell = new Cell[size]; // overflow and overflow_sink events } }
problem:
The example has an integer overflow defect because the integer y
is from an outside (and therefore, potentially tainted) source. This value is an operator in a multiplication operation (as size
), and then is used in a sink (allocator for mycell
).
Solution:
應付溢出的最佳方法仍是防範:充分了解數據的範圍,選擇恰當的變量類型。
4.Integer overflowed argument(整數參數的溢出)
example:
#include <unistd.h> #define INT_MAX 2147483647 class Cell { public: int a; int *b; }; void test(int x, int fd) { int y; read(fd, &y, 4); // y is from a tainted (outside) source int size = y; Cell *mycell; if (size != 0) { // Overflow results from operation size * sizeof(Cell) // Overflowed value is used in memory allocation mycell = new Cell[size]; // overflow and overflow_sink events }
problem:
The following example has an integer overflow defect because the integer y
is from an outside (and therefore, potentially tainted) source. This value is an operator in a multiplication operation (as size
), and then is used in a sink (allocator for mycell
).
Solution:
。。。
5.Copy into fixed size buffer(複製到固定大小的緩衝區)
example:
void string_overflow_example() { char destination_buffer[256]; char source_buffer[1024]; ... strcpy(destination_buffer, source_buffer); }
problem:
The above example flags a defect because, for the strcpy()
call, the source string is larger than the destination string.
Solution:
在往緩衝區複製數據前先對緩衝區的大小進行檢測,看是否會發生緩衝區大小不夠的狀況。
6.Destination buffer too small(目標緩衝區過小)
example:
void buffer_size_example() { static char source[] = "Twenty characters!!!"; char dest[10]; strncpy(dest, source, strlen(source)); }
problem:
In the above example, a call to strncpy()
generates an error because the length of the source string is twenty characters, but the destination string can only have a maximum of 10 characters:
Solution:
dest
should be length checked before being passed to the copy routine.
7.Untrusted value as argument(不受信任的值做爲參數)
example:
void tainted_scalar_example() { int nresp = packet_get_int(); if (nresp > 0) { response = xmalloc(nresp * sizeof(char *)); for (i = 0; i < nresp; i++) { // tainted scalar controls loop response[i] = packet_get_string(NULL); // heap corruption } } }
problem:
In the above example, the tainted integer nresp
, read from a packet, is only lower-bounds checked and not upper-bounds checked. This is a defect because a tainted expression—(nresp * sizeof(char *)
)— is being passed to xmalloc()
. This expression can cause an integer overflow, which can result in a buffer overflow, denial of service, memory corruption, or other security vulnerability.
Solution:
Properly sanitize the tainted variable before use. For example, the following is not a defect because nresp
's lower and upper bounds are checked before any dangerous uses.
Such as :
#define MAX_NRESP 256 ... void tainted_scalar_example() { int nresp = packet_get_int(); if (nresp > 0 && nresp < MAX_NRESP) { response = xmalloc(nresp * sizeof(char *)); for (i = 0; i < nresp; i++) { response[i] = packet_get_string(NULL); } } }
8.Insecure temporary file(不安全的臨時文件)
example:
void secure_temp_example() { char *tmp, *tmp2, *tmp3; char buffer[1024]; tmp = mktemp(buffer); }
problem:
The above example generates a defect because mktemp()
is insecure—it is easy to guess the name of the temporary file it creates. Similar functions include tmpnam()
, tempnam()
, and tmpfile()
.
Solution:
When using mkstemp(), remember to safely set the umask before to restrict the resulting temporary file permissions to only the owner. Also, do not pass on the filename to another privileged system call. Use the returned file descriptor instead.
9.Time of check time of use ---TOCTOU(計算機系統的資料與權限等狀態的檢查 與使用之間)
example:
void toctou_example() { stat(logfile, &st); if (st.st_uid != getuid()) return -1; open(logfile, O_RDWR); }
problem:
This program is susceptible to a file-based race condition because the logfile
binding can possibly change between the stat()
and open()
calls.
Solution: