With this article we open a series of publications devoted to the detection of errors and vulnerabilities in open-source projects using the static code analyzer
AppChecker . As part of this series, the most common defects in software code that could lead to serious vulnerabilities will be considered. Today we will focus on the null pointer dereferencing type defect.

The null pointer dereference (CWE-476) is a defect when a program accesses an incorrect pointer to some part of the memory. Such a call leads to an indefinite program behavior, which in most cases leads to a program crash.
Below is an example of a reference to a null pointer. In this case, most likely, the program will work without error messages.
')
#include <iostream> class A { public: void bar() { std::cout << "Test!\n"; } }; int main() { A* a = 0; a->bar(); return 0; }
And now let's look at an example in which the program crashes its work. The example is very similar to the previous one, but with a slight difference.
#include <iostream> class A { int x; public: void bar() { std::cout << x << "Test!\n"; } }; int main() { A* a = 0; a->bar(); return 0; }
Why in one case the program will work normally, but not in the other? The fact is that in the second case, the called method refers to one of the fields of the zero object, which will lead to reading information from the unpredictable area of the address space. In the first case, the method does not refer to the fields of the object, so the program is likely to complete correctly.
Consider the following C ++ snippet:
if( !pColl ) pColl->SetNextTxtFmtColl( *pDoc->GetTxtCollFromPool( nNxt ));
It is easy to see that if pColl == NULL, the body of this conditional statement will be executed. However, the pColl pointer is dereferenced in the operator's body, which is likely to lead to a crash of the program.
Usually such defects are caused by the negligence of the developer. Most often, blocks of this type are used in code to handle errors. To identify such defects, you can apply various methods of static analysis, for example, signature analysis or symbolic execution. In the first case, a signature is written that searches in an abstract syntax tree (AST) for a node of the “conditional operator” type, in the condition of which there is an expression of the form! a, a == 0, etc., and in the body of the operator there is an appeal to this object or dereferencing of this pointer. After that, it is necessary to filter out false positives, for example, before dereferencing this variable, the value can be assigned:
if(!a) { a = new A(); a->bar(); }
The expression in the condition may be non-trivial.
In the second case, during operation, the analyzer "monitors" which values the variables may have. After processing the if (! A) condition, the analyzer realizes that in the body of the conditional operator, the variable a is zero. Accordingly, its dereference can be considered an error.
The following code snippet is taken from the popular free office suite for Apache OpenOffice version 4.1.2. The defect in the code was detected using the AppChecker static code analyzer. The developers were notified of this defect, and released a patch in which this defect was
fixed ).
Consider a similar defect found in Oracle MySQL Server 5.7.10:
bool sp_check_name(LEX_STRING *ident) { if (!ident || !ident->str || !ident->str[0] || ident->str[ident->length-1] == ' ') { my_error(ER_SP_WRONG_NAME, MYF(0), ident->str); return true; } .. }
In this example, if ident is 0, then the condition will be true and the string will be executed:
my_error(ER_SP_WRONG_NAME, MYF(0), ident->str);
leading to a null pointer dereference. Apparently, the developer in the process of writing this piece of code in which errors are caught, simply did not realize that this situation may arise. The correct solution would be to make a separate error handler in case ident = 0.
It is not difficult to guess that dereferencing a null pointer is a defect independent of a programming language. The previous two examples showed code in C ++, but using the static analyzer AppChecker you can find similar problems in projects in Java and PHP. We give the relevant examples.
Consider the code snippet for managing and centralizing information about the construction of BIM Server version bimserver 1.4.0-FINAL-2015-11-04, written in Java:
if (requestUri.equals("") || requestUri.equals("/") || requestUri == null) { requestUri = "/index.html"; }
In this example, the requestUri variable is first accessed and only after that a check to a null pointer occurs. In order to avoid this defect, it was enough just to change the
order of these actions .
Now consider the code snippet of the popular phabricator web application collection written in php:
if (!$device) { throw new Exception( pht( 'Invalid device name ("%s"). There is no device with this name.', $device->getName())); }
In this case, the condition is satisfied only if $ device = NULL, but then $ device-> getName () is called, which will result in a fatal error.
Such defects may go unnoticed for a very long time, but at some point the condition will be fulfilled, which will lead to the collapse of the program. Despite the simplicity and seeming banality of such defects, they are quite common in both open-source and commercial projects.
Update:
Link to the free version of AppChecker:
https://file.cnpo.ru/index.php/s/o1cLkNrUX4plHMV