Skip to content

Missing C/C++ DataFlow/TaintTracking edges for fields accessed through pointers #19405

Closed
@MyEyes

Description

@MyEyes

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions