From 9a55d42639f16c64aa1fba2fe293706f2ebde697 Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Wed, 1 Apr 2020 15:29:45 +0200 Subject: [PATCH 1/2] C++: QLDoc in DefaultTaintTracking These docs are mostly copied and adapted from `DefaultTaintTrackingImpl.qll`. --- .../cpp/ir/dataflow/DefaultTaintTracking.qll | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll index d932ad30b87e..893de1c2af93 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll @@ -348,6 +348,16 @@ private Element adjustedSink(DataFlow::Node sink) { result.(AssignOperation).getAnOperand() = sink.asExpr() } +/** + * Holds if `tainted` may contain taint from `source`. + * + * A tainted expression is either directly user input, or is + * computed from user input in a way that users can probably + * control the exact output of the computation. + * + * This doesn't include data flow through global variables. + * If you need that you must call `taintedIncludingGlobalVars`. + */ cached predicate tainted(Expr source, Element tainted) { exists(DefaultTaintTrackingCfg cfg, DataFlow::Node sink | @@ -356,6 +366,21 @@ predicate tainted(Expr source, Element tainted) { ) } +/** + * Holds if `tainted` may contain taint from `source`, where the taint passed + * through a global variable named `globalVar`. + * + * A tainted expression is either directly user input, or is + * computed from user input in a way that users can probably + * control the exact output of the computation. + * + * This version gives the same results as tainted but also includes + * data flow through global variables. + * + * The parameter `globalVar` is the qualified name of the last global variable + * used to move the value from source to tainted. If the taint did not pass + * through a global variable, then `globalVar = ""`. + */ cached predicate taintedIncludingGlobalVars(Expr source, Element tainted, string globalVar) { tainted(source, tainted) and @@ -373,8 +398,19 @@ predicate taintedIncludingGlobalVars(Expr source, Element tainted, string global ) } +/** + * Gets the global variable whose qualified name is `id`. Use this predicate + * together with `taintedIncludingGlobalVars`. + */ GlobalOrNamespaceVariable globalVarFromId(string id) { id = result.getQualifiedName() } +/** + * Resolve potential target function(s) for `call`. + * + * If `call` is a call through a function pointer (`ExprCall`) or + * targets a virtual method, simple data flow analysis is performed + * in order to identify target(s). + */ Function resolveCall(Call call) { exists(CallInstruction callInstruction | callInstruction.getAST() = call and From bb3616e4c4cfc0ef6f2c8c5f65045acd4ef1326b Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Fri, 3 Apr 2020 17:51:35 +0200 Subject: [PATCH 2/2] C++: Add example for globalVarFromId --- .../semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll index 893de1c2af93..2cec0dc2a5aa 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll @@ -400,7 +400,14 @@ predicate taintedIncludingGlobalVars(Expr source, Element tainted, string global /** * Gets the global variable whose qualified name is `id`. Use this predicate - * together with `taintedIncludingGlobalVars`. + * together with `taintedIncludingGlobalVars`. Example: + * + * ``` + * exists(string varName | + * taintedIncludingGlobalVars(source, tainted, varName) and + * var = globalVarFromId(varName) + * ) + * ``` */ GlobalOrNamespaceVariable globalVarFromId(string id) { id = result.getQualifiedName() }