
The PVS-Studio analyzer has always been able to search for a variety of different security defects (potential vulnerabilities) in the program code. However, historically, we positioned PVS-Studio as a tool for finding errors. Now there is a fashion for searching in the code for vulnerabilities, not for errors, although in reality they are the same. Well, that means it's time to rebrand our static analyzer PVS-Studio. We start with Common Weakness Enumeration (CWE). This article provides a table that compares the PVS-Studio diagnostic warnings with a classifier. The table will be gradually replenished and changed, but now we can use it to write articles on detected security defects in a particular project. We think this will attract more attention to software security professionals to our tool.
Common Weakness Enumeration (CWE)
First, let's look at the terminology. For this, I will quote the
FAQ fragment from cwe.mitre.org.
A1. What is CWE? What is a software security defect?A common list of software security defects (Common Weakness Enumeration, CWE) is intended for software developers and specialists. It is an official registry or dictionary of common security defects that can manifest themselves in architecture, design, code or software implementation, and can be used by attackers to gain unauthorized access to the system. This list was developed as a universal formal language for describing software security defects, as well as a standard for measuring the effectiveness of tools that detect such defects, and for recognizing, eliminating, and preventing these defects.
')
Software security defects are defects, failures, errors, vulnerabilities and other problems of software implementation, code, design, or architecture that can make systems and networks vulnerable to malicious attacks if they are not corrected in time. Such problems include: buffer overflows, format string errors, etc .; problems of structure and evaluation of data validity; manipulations with special elements; channel and path errors; problems with handlers; user interface errors; directory traversal and problems with recognizing path equivalence; authentication errors; resource management errors; insufficient level of data verification; problems of evaluating incoming data and code implementation; problems of predictability and insufficient “randomness” of random numbers.
A2. What is the difference between a vulnerability and a software security defect?Security defects are errors that can trigger vulnerabilities. Vulnerabilities, such as those described in the Common Vulnerabilities and Exposures (CVE) list of common vulnerabilities and exposures, are program errors that can be directly used by an attacker to gain access to the system or network.
Correspondence between PVS-Studio and CWE warnings
We want the PVS-Studio analyzer to be perceived not only as a tool for finding errors, but also as a tool that helps reduce the number of vulnerabilities in the code. Of course, not every security defect listed in CWE is a vulnerability. Whether one or another defect can be used to attack depends on many factors. Therefore, in the future, we will write that the PVS-Studio analyzer does not reveal vulnerabilities, but potential vulnerabilities. It will be more correct.
So, I present the first version of the correspondence table. The table will be replenished and refined, but even the first version already allows you to make a general impression about the capabilities of the analyzer.
CWE | PVS-Studio | CWE Description |
CWE-14 | V597 | Compiler Removal of Code to Clear Buffers |
CWE-121 | V755 | Stack-based Buffer Overflow |
CWE-122 | V755 | Heap-based Buffer Overflow |
CWE-123 | V575 | Write-what-where Condition |
CWE-129 | V557, V781, V3106 | Improper Validation of Array Index |
CWE-131 | V514, V531, V568, V620, V627, V635, V641, V651, V687, V706, V727 | Incorrect Calculation of Buffer Size |
CWE-134 | V576, V618, V3025 | Use of Externally-Controlled Format String |
CWE-135 | V518, V635 | Incorrect Calculation of Multi-Byte String Length |
CWE-188 | V557, V3106 | Reliance on Data / Memory Layout |
CWE-195 | V569 | Signed to Unsigned Conversion Error |
CWE-197 | V642 | Numeric Truncation Error |
CWE-36 | V631, V3039 | Absolute Path Traversal |
CWE-369 | V609, V3064 | Divide by zero |
CWE-401 | V701, V773 | Release Memory Memory Removing Last Reference ('Memory Leak') |
CWE-404 | V611, V773 | Improper Resource Shutdown or Release |
CWE-415 | V586 | Double free |
CWE-416 | V774 | Use after free |
CWE-457 | V573, V614, V670, V3070, V3128 | Use of Uninitialized Variable |
CWE-462 | V766, V3058 | Duplicate Key in Associative List (Alist) |
CWE-467 | V511, V512, V568 | Use of sizeof () on a Pointer Type |
CWE-468 | V613, V620, V643 | Incorrect Pointer Scaling |
CWE-476 | V522, V595, V664, V757, V769, V3019, V3042, V3080, V3095, V3105, V3125 | NULL Pointer Dereference |
CWE-478 | V577, V719, V622, V3002 | Missing Default Case in Switch Statement |
CWE-481 | V559, V3055 | Assigning instead of comparing |
CWE-482 | V607 | Comparing instead of assigning |
CWE-483 | V640, V3043 | Incorrect Block Delimitation |
CWE-561 | V551, V695, V734, V776, V779, V3021 | Dead code |
CWE-562 | V558 | Return of Stack Variable Address |
CWE-563 | V519, V603, V751, V763, V3061, V3065, V3077, V3117 | Assignment to Variable without Use ('Unused Variable') |
CWE-570 | V501, V547, V560, V654, V3022, V3063 | Expression is Always False |
CWE-571 | V501, V547, V560, V617, V654, V694, V3022, V3063 | Expression is Always True |
CWE-587 | V566 | Assignment of a Fixed Address to a Pointer |
CWE-588 | V641 | Attempt to Access Child of Non-structure Pointer |
CWE-674 | V3110 | Uncontrolled Recursion |
CWE-690 | V522, V3080 | Unchecked Return Value to NULL Pointer Dereference |
CWE-762 | V611 | Mismatched Memory Management Routines |
CWE-805 | V512, V594, V3106 | Buffer Access with Incorrect Length Value |
CWE-806 | V512 | Buffer Access Size Buffer |
CWE-843 | V641 | Access of Resource Using Incompatible Type ('Type Confusion') |
Table N1. The first draft of the correspondence table for CWE and PVS-Studio diagnostics.Now we will be able to write in
articles about checking projects , what potential vulnerabilities have been found in this or that project. Since many people boast that their analyzers detect security defects, then we will touch on this topic in our articles.
Demonstration
Let's see how we can use the above table when writing articles. Let's analyze the project and look at the PVS-Studio diagnostic messages from the point of view of security defects.
Of course, not every project is worth exploring in terms of vulnerability. So let's take such a serious project as the Apache HTTP Server.
So, we check the Apache HTTP Server with the help of PVS-Studio and see that the bugs climb from all the slots. Stop! Now it is not bugs, but security defects! It is much more meaningful to talk about potential vulnerabilities than typos and errors.
I must say at once that this time we will not analyze the whole project, since our task is only to show the use of the table in practice. Let's stop on three warnings.
Example N1#define myConnConfig(c) \ (SSLConnRec *)ap_get_module_config(c->conn_config, &ssl_module) .... int ssl_callback_alpn_select(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) { conn_rec *c = (conn_rec*)SSL_get_app_data(ssl); SSLConnRec *sslconn = myConnConfig(c); apr_array_header_t *client_protos; const char *proposed; size_t len; int i; if (c == NULL) { return SSL_TLSEXT_ERR_OK; } .... }
The PVS-Studio analyzer issues a warning:
V595 The 'c' pointer was used before it was verified against nullptr. Check lines: 2340, 2348. ssl_engine_kernel.c 2340
In terms of security defects, this is:
CWE-476 (NULL Pointer Dereference)The essence of the error. Select the two most important code points:
SSLConnRec *sslconn = myConnConfig(c); if (c == NULL) {
The check
(c == NULL) tells us that the pointer may be null. However, it has already been
derelated within the
myConnConfig macro:
#define myConnConfig(c) \ (SSLConnRec *)ap_get_module_config(c->conn_config, &ssl_module)
Thus, the code is in no way protected from dereferencing the null pointer.
Example N2 int get_password(struct passwd_ctx *ctx) { char buf[MAX_STRING_LEN + 1]; .... memset(buf, '\0', sizeof(buf)); return 0; err_too_long: .... }
The PVS-Studio analyzer issues a warning:
V597 The compiler could delete the memset function call, which is used to flush the buf buffer. The memset_s () function should be used to erase the private data. passwd_common.c 165
In terms of security defects, this is:
CWE-14 (Compiler Removal of Code to Clear Buffers)The essence of the error. When compiling code in optimization mode, the compiler will remove the
memset function call, since from the compiler's point of view this call is superfluous. After filling with zeros of the buffer created on the stack, this buffer is no longer used. So filling the buffer with zeros is a waste of time and you should remove the
memset function call. Thus, private data will not be overwritten and will remain in memory.
I want to note that this is not an abstract theoretically possible behavior of the compiler. Compilers really do this to speed up our programs. Details:
Example N3 static int is_quoted_pair(const char *s) { int res = -1; int c; if (((s + 1) != NULL) && (*s == '\\')) { c = (int) *(s + 1); if (apr_isascii(c)) { res = 1; } } return (res); }
The PVS-Studio analyzer displays a warning:
V694 The condition ((s + 1)! = ((Void *) 0)) is only false if there is a pointer overflow which is undefined behavior anyway. mod_mime.c 531
In terms of security defects, this is:
CWE-571 (Expression is Always True)The essence of the error. The condition
((s + 1)! = NULL) is always true. It can be false only if the pointer overflows. Overflow of the pointer leads to indefinite program behavior, so there’s no point in talking about such a case. We can assume that the condition is always true, as the analyzer informed us about.
We are not the authors of the code and do not exactly know how the code should look, but, most likely, it should be like this:
if ((*(s + 1) != '\0') && (*s == '\\')) {
Conclusion
Cheers, PVS-Studio analyzer can be used to identify potential code vulnerabilities!
We invite everyone to learn more about the PVS-Studio code analyzer and try a demo version of the analyzer on your own projects. Product page:
PVS-Studio .
For all technical and licensing questions, please email us at support [@] viva64.com or use the
feedback form .
If you want to share this article with an English-speaking audience, then please use the link to the translation: Andrey Karpov, Phillip Khandeliants.
PVS-Studio: searching software weaknesses