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

Problems porting deprecated DataFlow to new IR DataFlow (field-involved) #16470

Open
f0rm2l1n opened this issue May 11, 2024 · 2 comments
Open
Assignees
Labels
C++ question Further information is requested

Comments

@f0rm2l1n
Copy link

Hello there, I'm trying to port my query from deprecated DataFlow to new IR DataFlow. However, due to the lack of clear documentation, I got myself stuck in the below scenarios.

The example C code is like below

  1 extern int** func1(int len);
  2 extern void func2(int *d[]);
  3
  4 struct st {
  5         int **data;
  6 };
  7
  8 void testfunc(struct st *ptr)
  9 {
 10         int **dp;
 11         ptr->data = func1(16);
 12         dp = ptr->data;
 13         func2(dp);
 14 }

While the query using old DataFlow is like the one below

import cpp
import semmle.code.cpp.Print
import semmle.code.cpp.dataflow.DataFlow

from DataFlow::Node source, DataFlow::Node end
where
  exists(FunctionCall fc | fc.getTarget().hasName("func1") | source.asExpr() = fc)
  and DataFlow::localFlow(source, end)
select source, source.getLocation(), end, end.getLocation()

In a nutshell, I want to use dataflow to trace the return value of calling func1. It's obvious that the analysis should track the flow to call of func2.
Running that query turned out well, I got result an entry like:

| call to func1 | file:///.../test.c:11:14:11:18 | dp                 | file:///.../test.c:13:8:13:9   |

Then, I port this query to the new IR Dataflow by change

import semmle.code.cpp.dataflow.DataFlow

to

import semmle.code.cpp.dataflow.new.DataFlow

And I cannot get the expected result but only the source node itself

| call to func1 | file:///.../test.c:11:14:11:18 | call to func1 | file:///.../test.c:11:14:11:18 |

I also try to replace the asExpr with some statements that don't exist in old DataFlow, such as asConvertedExpr(), asIndirectExpr(), etc. But no one works out.

I wonder whether this is my problem with using the new IR DataFlow, or the expected incapability of the new IR DataFlow to handle field-involved expression. If I change the example code to the below simple case:

extern int** func1(int len);
extern void func2(int *d[]);

void testfunc()
{
	int **dp1, **dp2;
	dp1 = func1(16);
	dp2 = dp1;
	func2(dp2);
}

Both the deprecated DataFlow and new DataFlow can track the call to func2.

Please help me write the new IR DataFlow query that can track the field-involved case. Thanks in advance.

@f0rm2l1n f0rm2l1n added the question Further information is requested label May 11, 2024
@mbg
Copy link
Member

mbg commented May 13, 2024

Hi @f0rm2l1n 👋

Could you try using taint flow instead of data flow for your query? I.e. semmle.code.cpp.dataflow.new.TaintTracking instead of semmle.code.cpp.dataflow.new.DataFlow.

@mbg mbg self-assigned this May 13, 2024
@mbg mbg added the C++ label May 13, 2024
@f0rm2l1n
Copy link
Author

Hi @f0rm2l1n 👋

Could you try using taint flow instead of data flow for your query? I.e. semmle.code.cpp.dataflow.new.TaintTracking instead of semmle.code.cpp.dataflow.new.DataFlow.

Hi @mbg, thanks for the reply!

Yeah, I tried to use new.TaintTracking and localTaint. However, still get the query result as localFlow.

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

from DataFlow::Node source, DataFlow::Node end
where
  exists(FunctionCall fc | fc.getTarget().hasName("func1") | source.asExpr() = fc)
  and TaintTracking::localTaint(source, end)
select source, source.getLocation(), end, end.getLocation()
| call to func1 | file:///.../test.c:11:14:11:18 | call to func1 | file:///.../test.c:11:14:11:18 |
| call to func1 | file:///.../test.c:11:14:11:18 | ... = ...     | file:///.../test.c:11:2:11:22  |

If I use deprecated TaintTracking and localTaint. I can get the func2 node,

Weird 🤔

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

No branches or pull requests

2 participants