Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[C++] Support for std::async and std::thread #18171

Open
JustusAdam opened this issue Nov 30, 2024 · 2 comments
Open

[C++] Support for std::async and std::thread #18171

JustusAdam opened this issue Nov 30, 2024 · 2 comments
Labels
question Further information is requested

Comments

@JustusAdam
Copy link

Are there any plans to support std::thread and std::async? I noticed that taint analysis does track through such calls. Are there any plans to do so in the future and is there a way to model around this?

@JustusAdam JustusAdam added the question Further information is requested label Nov 30, 2024
@redsun82
Copy link
Contributor

redsun82 commented Dec 2, 2024

Hey @JustusAdam!

We have no immediate plan of supporting those, as supporting them might currently mean sacrificing performance. We could obviously make support an opt-in, we will consider it. In the meantime, an isAdditionalFlowStep could help with those.

@JustusAdam
Copy link
Author

I tried the approach with additional flow steps but I'm not sure it really works for me. I tried this very simple example and it makes a flow from outer_result to target() appear, but somehow not the source() call. I might just be using the predicate wrong though.

#include <future>

int source()
{
    return 2;
}

int target(int source)
{
    return source;
}

void a_function(int result)
{
    target(result);
}

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

    int outer_result = source();
    auto fut = std::async(a_function, outer_result);
    fut.get();
    return 0;
}
import cpp
import FlowConfigs

predicate isAdditionalFlowStepImpl(DataFlow::Node node1, DataFlow::Node node2) {
  exists(FunctionCall async, int index |
    async.getTarget().getName() = "async" and
    (
      async.getArgument(index + 1) = node1.asExpr() and
      exists(Parameter p |
        node2.asParameter() = p and
        p.getFunction().getName() = "a_function" and
        p.getIndex() = index
      )
    )
  )
}

module MyConfig implements DataFlow::ConfigSig {
  predicate isSource(DataFlow::Node source) {
    any()
  }

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

  predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
    isAdditionalFlowStepImpl(node1, node2)
  }
}

module Flow = TaintTracking::Global<MyConfig>;

from DataFlow::Node node1, DataFlow::Node node2, Location loc
where
  Flow::flow(node1, node2) and
  loc.getFile().getBaseName() = "main.cpp" and
  node1.getLocation() = loc
select node1, node2, loc.getStartLine()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants