Closed
Description
Description of the issue
CodeQL seems to not handle data flow and taint tracking through fields of structs the way I expected when accessed through a pointer.
It's possible that I am misusing the library, but I would have expected the two cases below to behave basically identically under dataflow or taint tracking.
Mini reproducer
#include <stdlib.h>
struct A { int dummy; };
struct B { struct A *ptr; };
int main(int argc, char** argv)
{
struct B b = {0};
struct B* b_ptr = &b;
struct A *a_ptr = NULL;
//Flow from malloc into if stmt not identified by query below
b_ptr->ptr = malloc(sizeof(*b_ptr->ptr));
if(!b_ptr->ptr)
return -1;
//Flow from malloc into if stmt correctly identified by query below
a_ptr = malloc(sizeof(*a_ptr));
if(!a_ptr)
return -1;
return 0;
}
I am trying to query missing null checks after an allocation.
The query below only finds the second call to malloc
and the corresponding if statement.
import cpp
import semmle.code.cpp.dataflow.new.DataFlow
predicate flowsIntoIfStmt(FunctionCall fc, IfStmt if_stmt)
{
exists(DataFlow::Node src, DataFlow::Node dst |
src.asExpr() = fc
and if_stmt.getControllingExpr().getAChild*() = dst.asExpr()
and DataFlow::localFlow(src, dst))
}
from FunctionCall fc, IfStmt if_stmt
where flowsIntoIfStmt(fc, if_stmt)
select fc, if_stmt
I have observed the same behaviour using TaintTracking instead of DataFlow.