Skip to content

C++/Docs: add example based on NtohlArrayNoBound #2318

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

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions docs/language/learn-ql/cpp/dataflow.rst
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,49 @@ 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.

.. code-block:: ql

import cpp
import semmle.code.cpp.controlflow.Guards
import semmle.code.cpp.dataflow.TaintTracking

class NetworkToBufferSizeConfiguration extends TaintTracking::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 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
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
~~~~~~~~~

Expand Down