From 9e8455406f0a851cdff3356030cc77baf87e807d Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 13 Nov 2019 13:17:44 -0800 Subject: [PATCH 1/4] C++/Docs: add example based on NtohlArrayNoBound --- docs/language/learn-ql/cpp/dataflow.rst | 35 +++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/docs/language/learn-ql/cpp/dataflow.rst b/docs/language/learn-ql/cpp/dataflow.rst index 89f25913fbcc..ef48d30fd831 100644 --- a/docs/language/learn-ql/cpp/dataflow.rst +++ b/docs/language/learn-ql/cpp/dataflow.rst @@ -244,6 +244,41 @@ The following data flow configuration tracks data flow from environment variable select fopen, "This 'fopen' uses data from $@.", getenv, "call to 'getenv'" +The following taint tracking configuration tracks data from a call to ``ntohl`` to an array index operation. It uses the ``Guards`` library to recognize expressions that have been bounds checked and avoid propagating taint through them. + +.. code-block:: ql + + import cpp + import semmle.code.cpp.controlflow.Guards + import semmle.code.cpp.dataflow.TaintTracking + + class NetworkToBufferSizeConfiguration extends DataFlow::Configuration { + NetworkToBufferSizeConfiguration() { this = "NetworkToBufferSizeConfiguration" } + + override predicate isSource(DataFlow::Node node) { + node.asExpr().(FunctionCall).getTarget().hasGlobalName("ntohl") + } + + override predicate isSink(DataFlow::Node node) { + exists(ArrayExpr ae | node.asExpr() = ae.getArrayOffset()) + } + + override predicate isBarrier(DataFlow::Node node) { + exists(GuardCondition gc, Variable v | + gc.getAChild*() = v.getAnAccess() and + node.asExpr() = v.getAnAccess() and + gc.controls(node.asExpr().getBasicBlock(), _) + ) + } + } + + from DataFlow::Node ntohl, DataFlow::Node offset, NetworkToBufferSizeConfiguration conf + where conf.hasFlow(ntohl, offset) + select offset, "This array offset may be influenced by $@.", ntohl, + "converted data from the network" + + + Exercises ~~~~~~~~~ From f0b2aace1a2cb7168a0b12d581b11d81c983d997 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 13 Nov 2019 14:04:55 -0800 Subject: [PATCH 2/4] C++/Docs: add isAdditionalTaintStep to example --- docs/language/learn-ql/cpp/dataflow.rst | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/language/learn-ql/cpp/dataflow.rst b/docs/language/learn-ql/cpp/dataflow.rst index ef48d30fd831..1f83e772fb37 100644 --- a/docs/language/learn-ql/cpp/dataflow.rst +++ b/docs/language/learn-ql/cpp/dataflow.rst @@ -244,7 +244,7 @@ The following data flow configuration tracks data flow from environment variable select fopen, "This 'fopen' uses data from $@.", getenv, "call to 'getenv'" -The following taint tracking configuration tracks data from a call to ``ntohl`` to an array index operation. It uses the ``Guards`` library to recognize expressions that have been bounds checked and avoid propagating taint through them. +The following taint tracking configuration tracks data from a call to ``ntohl`` to an array index operation. It uses the ``Guards`` library to recognize expressions that have been bounds checked and avoid propagating taint through them. It also uses ``isAdditionalTaintStep`` to add flow from loop bounds to loop indexes. .. code-block:: ql @@ -252,7 +252,7 @@ The following taint tracking configuration tracks data from a call to ``ntohl`` import semmle.code.cpp.controlflow.Guards import semmle.code.cpp.dataflow.TaintTracking - class NetworkToBufferSizeConfiguration extends DataFlow::Configuration { + class NetworkToBufferSizeConfiguration extends TaintTracking::Configuration { NetworkToBufferSizeConfiguration() { this = "NetworkToBufferSizeConfiguration" } override predicate isSource(DataFlow::Node node) { @@ -263,7 +263,15 @@ The following taint tracking configuration tracks data from a call to ``ntohl`` exists(ArrayExpr ae | node.asExpr() = ae.getArrayOffset()) } - override predicate isBarrier(DataFlow::Node node) { + override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + exists(Loop loop, LoopCounter lc | + loop = lc.getALoop() and + loop.getControllingExpr().(RelationalOperation).getGreaterOperand() = pred.asExpr() | + succ.asExpr() = lc.getVariableAccessInLoop(loop) + ) + } + + override predicate isSanitizer(DataFlow::Node node) { exists(GuardCondition gc, Variable v | gc.getAChild*() = v.getAnAccess() and node.asExpr() = v.getAnAccess() and From dad1c96902a65b21d6bd24e381ebf5971862f422 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Thu, 14 Nov 2019 14:54:37 -0800 Subject: [PATCH 3/4] Docs: reword description of isSanitizer example --- docs/language/learn-ql/cpp/dataflow.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/language/learn-ql/cpp/dataflow.rst b/docs/language/learn-ql/cpp/dataflow.rst index 1f83e772fb37..9ba12f39d4cb 100644 --- a/docs/language/learn-ql/cpp/dataflow.rst +++ b/docs/language/learn-ql/cpp/dataflow.rst @@ -244,7 +244,7 @@ The following data flow configuration tracks data flow from environment variable select fopen, "This 'fopen' uses data from $@.", getenv, "call to 'getenv'" -The following taint tracking configuration tracks data from a call to ``ntohl`` to an array index operation. It uses the ``Guards`` library to recognize expressions that have been bounds checked and avoid propagating taint through them. It also uses ``isAdditionalTaintStep`` to add flow from loop bounds to loop indexes. +The following taint-tracking configuration tracks data from a call to ``ntohl`` to an array index operation. It uses the ``Guards`` library to recognize expressions that have been bounds-checked and defines ``isSanitizer`` to prevent taint from propagating through them. It also uses ``isAdditionalTaintStep`` to add flow from loop bounds to loop indexes. .. code-block:: ql From 15f50e6a38ed55069793f62fb7ea77a1c6de07e0 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 20 Nov 2019 15:44:29 -0800 Subject: [PATCH 4/4] Update docs/language/learn-ql/cpp/dataflow.rst Co-Authored-By: James Fletcher <42464962+jf205@users.noreply.github.com> --- docs/language/learn-ql/cpp/dataflow.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/language/learn-ql/cpp/dataflow.rst b/docs/language/learn-ql/cpp/dataflow.rst index 9ba12f39d4cb..f8d4c9c76114 100644 --- a/docs/language/learn-ql/cpp/dataflow.rst +++ b/docs/language/learn-ql/cpp/dataflow.rst @@ -244,7 +244,7 @@ The following data flow configuration tracks data flow from environment variable select fopen, "This 'fopen' uses data from $@.", getenv, "call to 'getenv'" -The following taint-tracking configuration tracks data from a call to ``ntohl`` to an array index operation. It uses the ``Guards`` library to recognize expressions that have been bounds-checked and defines ``isSanitizer`` to prevent taint from propagating through them. It also uses ``isAdditionalTaintStep`` to add flow from loop bounds to loop indexes. +The following taint-tracking configuration tracks data from a call to ``ntohl`` to an array index operation. It uses the ``Guards`` library to recognize expressions that have been bounds-checked, and defines ``isSanitizer`` to prevent taint from propagating through them. It also uses ``isAdditionalTaintStep`` to add flow from loop bounds to loop indexes. .. code-block:: ql