Last week we talked about the flaw in OpenSSL known as “Heartbleed” and it’s massive impact on websites and users around the world. We also mentioned how open-source scanning and support tools, such as OpenLogic, report this flaw. Today, we look at how Klocwork handles the issue.
Out of the box
The root cause of the Heartbleed issue is that a request to retrieve server memory for OpenSSL’s heartbeat function isn’t validated, resulting in an array access through
memcpy() potentially accessing data beyond the length of the array (and into memory that could contain sensitive information). Due to the use of a macro in the OpenSSL code that performs this function, this “tainted data” breach requires a few simple overrides that are fairly common practice when ensuring the analysis understands your project’s unique code.
Here is the relevant OpenSSL code with some interesting lines highlighted (click to enlarge):
The main culprit is the
memcpy() on line 1487 where
payload bytes is copied from
payload isn’t validated anywhere, it’s possible that more bytes than
pl contains are copied into
bp, resulting in unknown memory copied into
bp. This memory is eventually transmitted to the outside world (see lines 1492 and 1495).
Looking at line 1464, you’ll see why some analysis overrides are needed. The difficulty here is the
n2s() macro used to extract payload from
p is defined on line 1457 as
&s->s3->rrec.data. This macro effectively “hides” the propagation of data through the function and, of course, the analysis needs to know about it to be effective.
Using an override file and a custom knowledge base record, it’s pretty simple to tune Klocwork’s analysis to find this flaw. You don’t need any special version or upgrade to do this and, in fact, this is fairly common practice. First, create an override file that contains this macro override (the file must have a .h extension, so you can call it n2s.h):
#kw_override n2s(p, num) n2s_func((p), &(num))
This tells the Klocwork compiler to expand all instances of the
n2s() function in the source code to the analysis-specific definition specified here,
n2s_func(). Then, create your own knowledge base record to help Klocwork understand this particular macro (you can name the file n2s.kb):
n2s_func - TaintedIntData *$2
This record says that the function here returns potentially tainted integer data if the second argument points to a buffer that may contain tainted data (you can learn more about this syntax here). Once this tuning is done and an analysis performed, Klocwork reports the flaw as
SV.TAINTED.CALL.INDEX_ACCESS or, an unvalidated integer is being used to access an array (click to enlarge):
This tuning of Klocwork’s analysis isn’t specific to the Heartbleed problem but it does provide a real (and unfortunately, popular) example of how static code analysis can prevent some fairly serious issues.
And, in case you’re wondering, here’s how a comprehensive open source scanning and support tool like OpenLogic flags the issue (click to enlarge):