Vulnerability in terms of computer security is a flaw in the system that allows you to deliberately violate its integrity or cause incorrect operation. As practice shows, even a seemingly insignificant bug can be a serious vulnerability. Vulnerabilities can be avoided using various methods of software validation and verification, including static analysis. How PVS-Studio copes with the vulnerability search task is discussed.
PVS-Studio is a tool that prevents not only errors, but also vulnerabilities
How we came to this conclusion, I will tell a little lower. Here I wanted to talk about what PVS-Studio is.

')
PVS-Studio is a static code analyzer that looks for errors (and vulnerabilities, as you will see later) in programs written in C, C ++, C #. It works under Windows and Linux, it can be built into the Visual Studio IDE as a plugin. Currently, the analyzer implements over 450 diagnostic rules, each of which is accompanied by
documentation .
At the time of writing this article, using PVS-Studio, more than
280 open source projects were tested, in which over
11,000 errors were found. I wonder how many of these errors are vulnerabilities ...
Download and try PVS-Studio on the
official website .
By the way, we offer licenses for PVS-Studio to security experts. If you are a public security expert and are searching for vulnerabilities, email us for a license. You can read more about this offer in the article "
We provide the PVS-Studio analyzer to security experts ".
Terminology
If you are good at terminology, you know how CVE differs from CWE, and what they have in common, you can skip this section. I advise the rest to read, so that it is easier to understand further.
CWE (Common Weakness Enumeration) - a common list of security defects. Designed for software developers and security professionals. 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.
CVE (Common Vulnerabilities and Exposures) - program errors that can be directly used by hackers.
MITER began work on the classification of software vulnerabilities in 1999, when a list of common vulnerabilities and software exposure vulnerabilities (CVE) was based. In 2005, as part of the further development of the CVE system, a team of authors began work on a preliminary classification of vulnerabilities, attacks, failures and other types of security problems in order to define common software security defects. However, despite the self-sufficiency of the created classification within the CVE, it turned out to be too coarse for defining and classifying the code security assessment methods used by analyzers. To solve this problem, the CWE list was created.
PVS-Studio: other positioning
Prehistory
We have always positioned PVS-Studio as a tool for finding errors in the program code. The articles on the verification of projects used the appropriate terminology: bug, error, typo, etc. It is clear that different errors have different criticality: this code, most likely, is simply redundant and confuses the programmer, but because of this error, the entire system falls at 5 am every 3 days. It was clear, this concept did not receive further development for a long time - mistakes, they are mistakes.
However, over time, it turned out that some of the errors detected by PVS-Studio can be treated in a more serious way. For example, improper use of the
printf function can lead to much more negative consequences than outputting the wrong message in
stdout . When it became clear that with the help of many diagnostic rules, it was possible to detect not just errors, but potential vulnerabilities (CWE), it was decided to approach the issue in more detail and see how the PVS-Studio and CWE diagnostic rules relate.
Relationship of PVS-Studio and CWE alerts
Based on the results of work on identifying the relationship between the warnings of PVS-Studio and CWE, the following table was compiled:
CWE | PVS-Studio | CWE Description |
---|
CWE-14 | V597 | Compiler Removal of Code to Clear Buffers |
CWE-36 | V631, V3039 | Absolute Path Traversal |
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-190 | V636 | Integer overflow or wraparound |
CWE-193 | V645 | Off-by-one error |
CWE-252 | V522, V575 | Unchecked Return Value |
CWE-253 | V544, V545, V676, V716, V721, V724 | Incorrect Check of Function Return Value |
CWE-390 | V565 | Detection of Error Condition Without Action |
CWE-476 | V522, V595, V664, V757, V769, V3019, V3042, V3080, V3095, V3105, V3125 | NULL Pointer Dereference |
CWE-481 | V559, V3055 | Assigning instead of comparing |
CWE-482 | V607 | Comparing instead of assigning |
CWE-587 | V566 | Assignment of a Fixed Address to a Pointer |
CWE-369 | V609, V3064 | Divide by zero |
CWE-416 | V723, V774 | Use after free |
CWE-467 | V511, V512, V568 | Use of sizeof () on a Pointer Type |
CWE-805 | V512, V594, V3106 | Buffer Access with Incorrect Length Value |
CWE-806 | V512 | Buffer Access Size Buffer |
CWE-483 | V640, V3043 | Incorrect Block Delimitation |
CWE-134 | V576, V618, V3025 | Use of Externally-Controlled Format String |
CWE-135 | V518, V635 | Incorrect Calculation of Multi-Byte String Length |
CWE-462 | V766, V3058 | Duplicate Key in Associative List (Alist) |
CWE-401 | V701, V773 | Release Memory Memory Removing Last Reference ('Memory Leak') |
CWE-468 | V613, V620, V643 | Incorrect Pointer Scaling |
CWE-588 | V641 | Attempt to Access Child of Non-structure Pointer |
CWE-843 | V641 | Access of Resource Using Incompatible Type ('Type Confusion') |
CWE-131 | V512, V514, V531, V568, V620, V627, V635, V641, V645, V651, V687, V706, V727 | Incorrect Calculation of Buffer Size |
CWE-195 | V569 | Signed to Unsigned Conversion Error |
CWE-197 | V642 | Numeric Truncation Error |
CWE-762 | V611, V780 | Mismatched Memory Management Routines |
CWE-478 | V577, V719, V622, V3002 | Missing Default Case in Switch Statement |
CWE-415 | V586 | Double free |
CWE-188 | V557, V3106 | Reliance on Data / Memory Layout |
CWE-562 | V558 | Return of Stack Variable Address |
CWE-690 | V522, V3080 | Unchecked Return Value to NULL Pointer Dereference |
CWE-457 | V573, V614, V730, V670, V3070, V3128 | Use of Uninitialized Variable |
CWE-404 | V611, V773 | Improper Resource Shutdown or Release |
CWE-563 | V519, V603, V751, V763, V3061, V3065, V3077, V3117 | Assignment to Variable without Use ('Unused Variable') |
CWE-561 | V551, V695, V734, V776, V779, V3021 | Dead code |
CWE-570 | V501, V547, V517, V560, V625, V654, V3022, V3063 | Expression is Always False |
CWE-571 | V501, V547, V560, V617, V654, V694, V768, V3022, V3063 | Expression is Always True |
CWE-670 | V696 | Always-Incorrect Control Flow Implementation |
CWE-674 | V3110 | Uncontrolled Recursion |
CWE-681 | V601 | Incorrect Conversion between Numeric Types |
CWE-688 | V549 | Function Call With Incorrect Variable Or Reference As Argument |
CWE-697 | V556, V668 | Insufficient Comparison |
Table N1 - Draft version of the correspondence table of CWE and PVS-Studio diagnostics
This is not the final version of the table, but it does provide some insight into how PVS-Studio and CWE warnings relate to each other. Now it became clear that PVS-Studio successfully finds (and always finds) in the program code not just bugs, but potential vulnerabilities, that is, CWE. Several articles have been written on this topic, their list is given at the end of the current article.
CVE bases

Potential Vulnerability (CWE) is not yet a Vulnerability (CVE). The real vulnerabilities found in both open source and proprietary projects are collected at
http://cve.mitre.org . There you can see a description of a specific vulnerability, find additional links (for example, to a discussion, a bulletin of vulnerability fixes, links to commits covering vulnerabilities, etc.). If desired, this database can be unloaded entirely in the format of interest. At the time of this writing, the database in text format was a .txt file with a size of about 100 MB and a volume of more than 2.7 million lines. Very impressive, agree.

In the course of the work, I found another interesting resource that can be useful to those interested -
http://www.cvedetails.com/ . It is convenient in that it gives opportunities such as:
- CVE lookup by CWE ID;
- search CVE in a specific product;
- viewing statistics on the appearance / fixes of vulnerabilities;
- viewing various data tables related in one way or another to CVE (for example, the rating of firms in whose software products the most vulnerabilities were found);
- etc.
Some CVEs that could be found with PVS-Studio
I am writing this article in order to demonstrate that the PVS-Studio analyzer can protect an application from vulnerabilities (at least from some of them).
We never investigated whether a particular defect discovered by PVS-Studio could be exploited as a vulnerability. It is difficult, and we are not facing such a task. Therefore, I will act differently: I will take several vulnerabilities that have already been discovered and described, and demonstrate that they could have been avoided if the code were regularly checked using PVS-Studio.
Note The vulnerabilities described in the article were not found in synthetic examples, but in real source files taken from old project revisions.
illumos-gate

The first vulnerability, which will be discussed, was discovered in the source code of the illumos-gate project. illumos-gate is an open source project (available in the
repository on GitHub ) that forms the core of the operating system, rooted in Unix and BSD.
The vulnerability has the code name
CVE-2014-9491 .
CVE-2014-9491 Description : It’s not a
challenge , which makes it possible to send a message through the unspecified vectors.
The problem code was in the
devzvol_readdir function and looked like this:
static int devzvol_readdir(....) { .... char *ptr; .... ptr = strchr(ptr + 1, '/') + 1; rw_exit(&sdvp->sdev_contents); sdev_iter_datasets(dvp, ZFS_IOC_DATASET_LIST_NEXT, ptr); .... }
The
strchr function returns a pointer to the first occurrence of the character passed as the second argument. However, the function may return a null pointer if the character was not found in the source string. But this fact has been forgotten or not taken into account. As a result, 1 is simply added to the return value, the result is written to the
ptr variable, and then the pointer is operated “as is”. If the received pointer was zero, then adding a unit to it, we get an invalid pointer, checking which for
NULL inequality will not mean its validity. Under certain conditions, this code could lead to the emergence of a
kernel panic .
PVS-Studio detects this vulnerability using the
V769 diagnostic rule,
stating that the pointer returned by the
strchr function can be zero, and at the same time it deteriorates (due to the addition 1):
V769 The 'strchr (ptr + 1,' / ')' pointer in the 'strchr (ptr + 1,' / ') + 1' expression could be nullptr. In such a case, it will not be used.
Network audio system
Network Audio System (NAS) is an open source client-server audio transmission system
available on SourceForge . NAS works both under Unix and under Windows.
The vulnerability discovered in this project has the code name
CVE-2013-4258 .
CVE-2013-4258 Description : Function in server / os / aulog.c in Network Audio System (NAS) 1.9.3 allows you to remotely via the system.
syslog related format specifiers in unspecified vectors.
The code looked like this:
.... if (NasConfig.DoDaemon) { openlog("nas", LOG_PID, LOG_DAEMON); syslog(LOG_DEBUG, buf); closelog(); } else { errfd = stderr; ....
This code snippet incorrectly uses the
syslog function. The declaration of this function is as follows:
void syslog(int priority, const char *format, ...);
The second parameter must be a format string, and the subsequent ones must be the data required by this string. Here, there is no format string, and the target message is directly passed as an argument (variable
buf ). This caused a vulnerability that could lead to the execution of arbitrary code.
If you believe the
entries in the SecurityFocus database , the vulnerability was manifested in the Debian and Gentoo operating systems.
What is PVS-Studio? PVS-Studio detects this error using the
V618 diagnostic rule and issues a warning:
V618 It is dangerous to call the specification of the syslog. The example of the safe code: printf ("% s", str);
The function of annotation of functions implemented in the analyzer and a large number of annotations help to detect this and similar errors - now their number exceeds 6500 for C, C ++ and 900 for C #.
The correct call to this function, closing this vulnerability, is as follows:
syslog(LOG_DEBUG, "%s", buf);
It uses the format string
"% s" , which makes the
syslog function call safe.
Ytnef (Yerase's TNEF Stream Reader)
Ytnef is an open source program
available on GitHub . Designed to decode TNEF streams, such as those created in Outlook.
Over the past part of 2017, it revealed a number of vulnerabilities described
here . Consider one of the CVE entries described in this list —
CVE-2017-6298 .
Description CVE-2017-6298 : An issue was discovered in ytnef before 1.9.1. This is related to a patch described as "1 of 9. Null Pointer Deref / calloc return value not checked."
All the corrected places where a null pointer dereference could occur had approximately the same form:
vl->data = calloc(vl->size, sizeof(WORD)); temp_word = SwapWord((BYTE*)d, sizeof(WORD)); memcpy(vl->data, &temp_word, vl->size);
In all such places, vulnerabilities are related to the misuse of the
calloc function. This function can return a null pointer if it was not possible to allocate the requested memory block. But the resulting pointer is not checked for
NULL inequality, but is used on the assumption that
calloc will always return a non-zero pointer. This is somewhat imprudent.
How does PVS-Studio cope with the detection of such vulnerabilities? Quite easy: the analyzer implements many different diagnostic rules that detect operation with zero pointers.
In particular, the vulnerabilities described above will be detected using the
V575 diagnostic rule. The warning is as follows:
V575 The potential null pointer has passed into 'memcpy' function. Inspect the first argument.
The analyzer has detected that a potentially null pointer resulting from a call to the
calloc function is passed to the
memcpy function without checking for
NULL inequality.
Thus, PVS-Studio also detected this vulnerability. But if the analyzer were used regularly in the process of writing code, then this problem could have been prevented even before it got into the version control system ...
Mysql

MySQL is a free relational database management system. Typically, MySQL is used as a server that is accessed by local or remote clients, but the distribution package includes an internal server library that allows you to include MySQL in standalone programs.
Consider one of the vulnerabilities found in this project -
CVE-2012-2122 .
Description CVE-2012-2122: sql /
password.c in Oracle MySQL 5.1.x before 5.1.63, 5.5.x before 5.5.24, and 5.6.x before 5.6.6, and MariaDB 5.1.x before 5.1.62, 5.2.x before 5.2.12, 5.3.x before 5.3.6, and 5.5.x before 5.5.23, it allows improperly checked return value
.Here is the code that contains the vulnerability:
typedef char my_bool; my_bool check_scramble(const char *scramble_arg, const char *message, const uint8 *hash_stage2) { .... return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE); }
The
memcmp function
return type is
int , and the
check_scramble function return type is
my_bool , in fact,
char . As a result, an implicit casting of
int to
char occurs, in which the values ​​of the high-order bits are discarded. This led to the fact that in about 1 case out of 256 it was possible to connect with any password, knowing the username. Due to the fact that 300 connection attempts took less than a second, this protection is as good as its absence. You can read more about this vulnerability through the links mentioned on the
CVE-2012-2122 page .
PVS-Studio detects this problem using the
V642 diagnostic rule. The warning is as follows:
V642 Saving the 'memcmp' function result inside the 'char' type variable is inappropriate. Breaking the program's logic. password.c
It turns out that this vulnerability was discovered using PVS-Studio.
iOS

iOS is a mobile operating system for smartphones, electronic tablets and wearable players, developed and produced by the American company Apple.
Consider one of the vulnerabilities to which this operating system was exposed -
CVE-2014-1266 . Fortunately, in the general access there is a code fragment from which it is clear what the problem was.
Description of Vulnerability CVE-2014-1266 : The
SSL function of libsecurity_ssl / lib / sslKeyExchange.c and the TV 6.x before 6.0.2, and Apple OS X 10.9.x before 10.9.2 TLS Server Key Exchange message, which allows you to download SSL servers by (1) (or) (2) omitting the signing step.
The code snippet that led to the vulnerability was as follows:
static OSStatus SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams, uint8_t *signature, UInt16 signatureLen) { OSStatus err; .... if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail; .... fail: SSLFreeBuffer(&signedHashes); SSLFreeBuffer(&hashCtx); return err; }
The problem lies in the two
goto operators, located next to each other. Only the first of these operators refers to the
if operator, the second does not. Thus, regardless of the values ​​of the previous conditions, the transition to the label
fail will be made. Due to the execution of the second
goto statement , the
err value will be successful. This led to the fact that attackers could deceive the SSL server.
PVS-Studio detects this problem using two diagnostic rules at once -
V640 and
V779 . The warnings are as follows:
- V640 The code's operational logic does not correspond with its formatting. The statement is indented. It is possible that curly brackets are missing.
- V779 Unreachable code detected. It is possible that an error is present
Thus, the analyzer warns at once about several things that seemed suspicious to him:
- The logic of the program does not match the design of the code: judging by the alignment, it seems that both goto operators belong to the if operator, but this is not so. The first goto statement is indeed a condition, the second is not;
- presence of unreachable code: since the second goto statement is executed unconditionally, the code following it will not be executed.
It turns out that here PVS-Studio has successfully coped with its work.
Effective use of static analysis
The goal of this article, as I mentioned earlier, is to show that PVS-Studio successfully deals with the search for vulnerabilities. The approach chosen to achieve this goal is to demonstrate that the analyzer successfully finds some known vulnerabilities. The material above was necessary to confirm the fact that vulnerabilities can be searched using static analysis.
Now I would like to talk about how to do it most effectively. Ideally, vulnerabilities should be discovered before they become such (that is, when someone finds them and understands how to exploit them), and the sooner they are found, the better. If used correctly, static vulnerability analysis can be detected even at the coding stage. How this can be achieved will be described below.
Note. In this section, for consistency, I use the word "mistakes." But simple mistakes, as we have seen, can be potential, and then valid vulnerabilities. Please do not forget about it.
In general, the earlier the error is detected and fixed, the cheaper the cost of fixing it. The figure below shows the data from the book Applied Software Measurement from Capers Jones.

As can be seen from the graphs, approximately 85% of errors are made at the coding stage, while the cost of correction at this stage is minimal. At the same time, as the error exists in the program code, the cost of correcting it constantly increases, and if at the coding stage, the elimination of the error will cost about $ 25, then after the release of the software product, this figure increases to tens of thousands of dollars. About the cost of vulnerabilities discovered after the release, even not worth it.
From here follows a simple conclusion - the earlier the error is detected and corrected, the better. The purpose of static analysis is to detect errors in the code as early as possible. Static analysis is not a substitute for other software validation and verification tools, but complements them.
How to get the maximum benefit from the use of a static analyzer? The first rule - the code should be checked regularly. Ideally, the error should be corrected at the stage of writing the code, before it is embedded in the version control system.
However, it may be inconvenient to run constant checks on the developer’s machine. In addition, the operation of checking the entire code can be quite long, which does not allow to frequently recheck the code after revisions. In PVS-Studio, for this purpose, an
incremental analysis mode is implemented, which allows analyzing only the code that has been changed / affected since the last build. Moreover, this function allows you to run the analysis automatically after assembly, which allows the developer not to be distracted by the independent launch of the analysis. After completion of the analysis, if errors were found in the modified files, the programmer will be given the appropriate notification.
Even under the condition of such use, errors may occur in the version control system. Therefore, you need to have a "second level of protection" - the use of a static analyzer on the build server. For example, integrate code analysis into the nightly build process. This will allow you to regularly check the projects at night, and in the morning to get information about what errors have entered the version control system. The important point in this case is the need to quickly correct errors found in this way - preferably the next day. Otherwise, over time, the appearance of new errors simply no one will pay attention, and there will be no sense from such checks.
Implementing static analysis in the development process may seem like a non-trivial task if the project is not developed from scratch. For information on how to properly start using static analysis in this case, see the article "
How to quickly implement static analysis in a large project? "
Conclusion
I hope I managed to show you that:
- even a seemingly simple bug can be a serious vulnerability;
- PVS-Studio successfully handles not only the search for errors in the code, but also the search for CWE and CVE.
And if the cost of a simple error in the code increases significantly over time, then there is nothing to say about the cost of vulnerabilities ... At the same time, if you use static analysis, many vulnerabilities can be fixed even before they get into the version control system, not to mention so that someone finds and exploits them.
Finally, I would advise you to try
PVS-Studio on your project - suddenly you will be able to find something interesting that will save your project from falling into CVE databases.
Additional links
If you want to share this article with an English-speaking audience, then please use the link to the translation: Sergey Vasiliev.
How Can PVS-Studio Help in the Detection of Vulnerabilities?