github / codeql

CodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security
https://codeql.github.com
MIT License
7.75k stars 1.56k forks source link

[C++] Assigning to function pointer in a function appears to defeat dispatch analysis #18103

Open JustusAdam opened 5 days ago

JustusAdam commented 5 days ago

Assigning to a function pointer in a function appears to defeat the points-to analysis used to resolve the dispatch of function pointers.

In the following example I would have expected to see two flows from source() to target() but only the second one from the direct assignment of the function pointer is reported.

int source()
{
    return 2;
}

int a_function()
{
    return source();
}

int target(int source)
{
    return source;
}

void set(int (**ptr)(), int (*ptr2)())
{
    *ptr = ptr2;
}

int main(int argv, char **argc)
{
    int (*fptr)();

    set(&fptr, a_function);

    target(fptr()); // not detected as source

    fptr = a_function;

    target(fptr()); // detected

    return 0;
}

This is the complete query

import cpp
import semmle.code.cpp.dataflow.new.TaintTracking

module SourceSinkCallConfig implements DataFlow::ConfigSig {
  predicate isSource(DataFlow::Node source) {
    source.asExpr().(FunctionCall).getTarget().getName() = "source"
  }

  predicate isSink(DataFlow::Node sink) {
    exists(Call call |
      call.getTarget().getName() = "target" and
      call.getArgument(0) = sink.asExpr()
    )
  }
}

module SourceSinkCallTaint = TaintTracking::Global<SourceSinkCallConfig>;

from DataFlow::Node source, DataFlow::Node sink, int source_line, int sink_line
where
  SourceSinkCallTaint::flow(source, sink) and
  source_line = source.getLocation().getStartLine() and
  sink_line = sink.getLocation().getStartLine()
select source, source_line, sink, sink_line

This is the output. I would have expected to also see a flow to line 28.

|     source     | source_line |        sink        | sink_line |
+----------------+-------------+--------------------+-----------+
| call to source |           9 | call to expression |        32 |

CodeQL version: 2.19.3

redsun82 commented 4 days ago

👋 @JustusAdam thanks for reaching out to us for this!

As with https://github.com/github/codeql/issues/18102, I think that may indeed be a limitation, but I will try to confirm tomorrow. If it is, I will make sure we have this in our backlog of things to improve!

redsun82 commented 2 days ago

I've created an internal issue to track this.