In the provides an experimental checker alpha.security.taint.TaintPropagation for performing static taint analysis. Implemented as for details on using existing taint checkers and CodeQL to find memory corruption bugs.
One has to be careful with this approach to avoid missing potential taint sources. Though MySQL Cluster has defined APIs like Signal::getDataPtr() to fetch the Signal data pointer, various handlers don’t follow the standard. Instead, signal->theData is accessed in numerous other ways from offset 0 or from various other offsets. I rewrote some common patterns using find and sed. This may not be exhaustive but provides sufficient taint sources to experiment with the checkers.
The situation is much different when working with CodeQL, where defining taint sources is far more flexible. All we have to do is override the isSource() predicate to something like this:
CWE-822: Untrusted Pointer Dereference
In an :
The with a path length of 1. Here is an example bug report:

Using a known bug pattern, it is possible to apply filters to reduce the results in addition to the taint check. For example, we can check the AST statements for pointer loads which are only assignment statements like above. The checker can be tweaked as per the nature of bugs in the codebase.
Analyzing memory loads using CodeQL IR
To perform a similar analysis in CodeQL, one can possibly rely on expression classes such as PointerDereferenceExpr, VariableAccess, FieldAccess and its subtypes. But in this case, I was curious to explore CodeQL’s relies on 2 operands - a source address operand (r17303_4) and a source value operand (m17300_12). The source value operand is a documentation, I found a couple of features that could be useful for refining the query: the overlap relationship and VirtualVariables.
Overlap defines the relationship between the definition of a memory location and its usage. The most interesting relationship for this analysis is MustExactlyOverlap - the set of bits written by the definition is identical to the set of bits read by the use, and the data type of both the definition and the use are the same. For more clarity on the overlap relationship, refer to the are the ones that do not have an exactly overlapping relationship. This can also be checked using , values from an untrusted source are used for loop termination conditions. This may lead to a DoS or other issues depending on the operations done in the loop body. This section provides details about detecting such tainted loop conditions using CSA and CodeQL.
Detecting tainted loop condition using CSA
Unlike tainted memory loads, I couldn’t find any path-sensitive callback to trigger on loop conditions. Moreover, AST-based matchers without path-sensitivity are not useful in this case. Therefore, I relied on the check::BranchCondition callback which fires every time a control flow branching occurs during analysis. The following information is from the checker documentation:
The idea here is, whenever the callback triggers due to a conditional statement, walk up the AST using compared against untrusted values, or untrusted values used as induction variables to decide on loop termination. Consider a couple of common code patterns below that involve explicit in loop statements, especially while and do while loops:
No special breakdown is necessary in case of unary operations in the way we handled binary operations. However, in certain cases, . Since Signal data is treated as an unsigned 32-bit integer in most cases, I queried if the variable can take a value greater than 0x10000. If yes, consider the variable as unconstrained and log the bug.
Configuring analyzer-max-loop in CSA
Clang analyzer has a configuration parameter to choose the number of times a basic block in a loop gets executed. By default, this value is 4.
So how does it matter in our analysis? Consider the below code:
Here is buffer->index is validated and the loop operation is considered safe. But the checker still reports a false positive bug.
What seems to be happening here is, the symbolic expression gets evaluated analyzer-max-loop number of times i.e., for each visit to the basic block.
The analyzer seems to evaluate that the decrement operation can underflow resulting in a value greater than 0x10000, therefore reporting it as a bug. I’m not entirely sure of the right way to solve this issue, but a quick workaround is to set analyzer-max-loop to 1. This can also be done in by Lucas. All this analysis was performed on clang 12.0 and MySQL Cluster 8.0.25
Scanning with CodeQL requires creating a database, followed by running any queries we are interested in against the created database.
The source code for the Clang checkers and CodeQL queries can be found
•
•
•
Conclusion
We hope you’ve enjoyed this look at finding bugs using Clang Static Analyzer, CodeQL, and Binary Ninja. As ZDI Vulnerability Analysts, these have proved helpful in finding new bugs. If you use these (or other) tools to find bugs of your own, consider submitting them to our program. Until then, you can find me on Twitter for the latest in exploit techniques and security patches.
SOCIAL SHARE CARD GENERATOR