C++: repair the ReturnCstr query

This commit is contained in:
Robert Marsh
2022-10-26 11:02:23 -04:00
parent fc9f239a3b
commit de89b4c69f
2 changed files with 16 additions and 13 deletions

View File

@@ -36,20 +36,20 @@ class StdString extends Class {
* Holds if `e` is a direct or indirect reference to a locally
* allocated `std::string`.
*/
predicate refToStdString(Expr e, ConstructorCall source) {
predicate refToStdString(DataFlow::Node node, ConstructorCall source) {
exists(StdString stdstring |
stdstring.getAMemberFunction() = source.getTarget() and
not exists(LocalVariable v |
source = v.getInitializer().getExpr() and
v.isStatic()
) and
e = source
node.asExpr() = source
)
or
// Indirect use.
exists(Expr prev |
exists(DataFlow::Node prev |
refToStdString(prev, source) and
DataFlow::localFlowStep(DataFlow::exprNode(prev), DataFlow::exprNode(e))
DataFlow::localFlowStep(prev, node)
)
}
@@ -74,29 +74,30 @@ predicate flowFunction(Function fcn, int argIndex) {
* Holds if `e` is a direct or indirect reference to the result of calling
* `c_str` on a locally allocated `std::string`.
*/
predicate refToCStr(Expr e, ConstructorCall source) {
exists(MemberFunction f, FunctionCall call |
predicate refToCStr(DataFlow::Node node, ConstructorCall source) {
exists(MemberFunction f, FunctionCall call, DataFlow::Node qualifier |
f.getName() = "c_str" and
call = e and
call = node.asExpr() and
call.getTarget() = f and
refToStdString(call.getQualifier(), source)
qualifier.asIndirectArgument() = call.getQualifier() and
refToStdString(qualifier, source)
)
or
// Indirect use.
exists(Expr prev |
exists(DataFlow::Node prev |
refToCStr(prev, source) and
DataFlow::localFlowStep(DataFlow::exprNode(prev), DataFlow::exprNode(e))
DataFlow::localFlowStep(prev, node)
)
or
// Some functions, such as `JNIEnv::NewStringUTF()` (from Java's JNI)
// embed return a structure containing a reference to the C-style string.
exists(Function f, int argIndex |
flowFunction(f, argIndex) and
f = e.(Call).getTarget() and
refToCStr(e.(Call).getArgument(argIndex), source)
f = node.asExpr().(Call).getTarget() and
refToCStr(DataFlow::exprNode(node.asExpr().(Call).getArgument(argIndex)), source)
)
}
from ReturnStmt r, ConstructorCall source
where refToCStr(r.getExpr(), source)
where refToCStr(DataFlow::exprNode(r.getExpr()), source)
select r, "Return value may contain a dangling pointer to $@.", source, "this local std::string"

View File

@@ -1 +1,3 @@
| test.cpp:24:3:24:26 | return ... | Return value may contain a dangling pointer to $@. | test.cpp:23:24:23:37 | call to basic_string | this local std::string |
| test.cpp:32:3:32:44 | return ... | Return value may contain a dangling pointer to $@. | test.cpp:32:10:32:35 | call to basic_string | this local std::string |
| test.cpp:45:3:45:42 | return ... | Return value may contain a dangling pointer to $@. | test.cpp:44:22:44:35 | call to basic_string | this local std::string |