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: