C++: NonConstantFormat taint only for string types

To speed up the taint analysis in `NonConstantFormat.ql` and to remove
FPs that were due to taint spreading from `i` to `a[i]`, this commit
stops the taint tracking in `NonConstantFormat.ql` at every node that
could not possibly contain a string.

I tested performance on Wireshark, and it's fine. Pulling out the
`isSanitizerNode` prevented `isSanitizer` from turning into four
half-slow RA predicates due to both CPE and `#antijoin_rhs`
transformations happening.
This commit is contained in:
Jonas Jensen
2019-06-20 14:31:34 +02:00
parent e99c68885c
commit cace411974
3 changed files with 22 additions and 4 deletions

View File

@@ -51,6 +51,15 @@ predicate underscoreMacro(Expr e) {
)
}
/**
* Holds if `t` cannot hold a character array, directly or indirectly.
*/
predicate cannotContainString(Type t) {
t.getUnspecifiedType() instanceof BuiltInType
or
t.getUnspecifiedType() instanceof IntegralOrEnumType
}
predicate isNonConst(DataFlow::Node node) {
exists(Expr e | e = node.asExpr() |
exists(FunctionCall fc | fc = e.(FunctionCall) |
@@ -99,16 +108,26 @@ predicate isNonConst(DataFlow::Node node) {
node instanceof DataFlow::DefinitionByReferenceNode
}
pragma[noinline]
predicate isSanitizerNode(DataFlow::Node node) {
underscoreMacro(node.asExpr())
or
cannotContainString(node.getType())
}
class NonConstFlow extends TaintTracking::Configuration {
NonConstFlow() { this = "NonConstFlow" }
override predicate isSource(DataFlow::Node source) { isNonConst(source) }
override predicate isSource(DataFlow::Node source) {
isNonConst(source) and
not cannotContainString(source.getType())
}
override predicate isSink(DataFlow::Node sink) {
exists(FormattingFunctionCall fc | sink.asExpr() = fc.getArgument(fc.getFormatParameterIndex()))
}
override predicate isSanitizer(DataFlow::Node node) { underscoreMacro(node.asExpr()) }
override predicate isSanitizer(DataFlow::Node node) { isSanitizerNode(node) }
}
from FormattingFunctionCall call, Expr formatString

View File

@@ -18,4 +18,3 @@
| test.cpp:85:12:85:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:90:12:90:18 | ++ ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:107:12:107:24 | new[] | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:142:10:142:20 | access to array | The format string argument to printf should be constant to prevent security issues and other potential errors. |

View File

@@ -139,5 +139,5 @@ void set_value_of(int *i);
void print_ith_message() {
int i;
set_value_of(&i);
printf(messages[i], 1U); // GOOD [FALSE POSITIVE]
printf(messages[i], 1U); // GOOD
}