Skip to content

Commit 64ce6b4

Browse files
authored
Merge pull request #256 from jketema/tainted-path-update
Update FIO32-C with the latest version of the query from CodeQL
2 parents 760c05b + d1c0a5d commit 64ce6b4

File tree

3 files changed

+19
-50
lines changed

3 files changed

+19
-50
lines changed

c/cert/src/rules/FIO32-C/DoNotPerformFileOperationsOnDevices.ql

Lines changed: 15 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
import cpp
1515
import codingstandards.c.cert
1616
import semmle.code.cpp.security.FunctionWithWrappers
17-
import semmle.code.cpp.security.Security
17+
import semmle.code.cpp.security.FlowSources
1818
import semmle.code.cpp.ir.IR
1919
import semmle.code.cpp.ir.dataflow.TaintTracking
20-
import DataFlow::PathGraph
20+
import TaintedPath::PathGraph
2121

2222
// Query TaintedPath.ql from the CodeQL standard library
2323
/**
@@ -46,22 +46,6 @@ class FileFunction extends FunctionWithWrappers {
4646
override predicate interestingArg(int arg) { arg = 0 }
4747
}
4848

49-
Expr asSourceExpr(DataFlow::Node node) {
50-
result = node.asConvertedExpr()
51-
or
52-
result = node.asDefiningArgument()
53-
}
54-
55-
Expr asSinkExpr(DataFlow::Node node) {
56-
result =
57-
node.asOperand()
58-
.(SideEffectOperand)
59-
.getUse()
60-
.(ReadSideEffectInstruction)
61-
.getArgumentDef()
62-
.getUnconvertedResultExpression()
63-
}
64-
6549
/**
6650
* Holds for a variable that has any kind of upper-bound check anywhere in the program.
6751
* This is biased towards being inclusive and being a coarse overapproximation because
@@ -85,20 +69,16 @@ predicate hasUpperBoundsCheck(Variable var) {
8569
)
8670
}
8771

88-
class TaintedPathConfiguration extends TaintTracking::Configuration {
89-
TaintedPathConfiguration() { this = "TaintedPathConfiguration" }
90-
91-
override predicate isSource(DataFlow::Node node) { isUserInput(asSourceExpr(node), _) }
72+
module TaintedPathConfiguration implements DataFlow::ConfigSig {
73+
predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
9274

93-
override predicate isSink(DataFlow::Node node) {
75+
predicate isSink(DataFlow::Node node) {
9476
exists(FileFunction fileFunction |
95-
fileFunction.outermostWrapperFunctionCall(asSinkExpr(node), _)
77+
fileFunction.outermostWrapperFunctionCall(node.asIndirectArgument(), _)
9678
)
9779
}
9880

99-
override predicate isSanitizerIn(DataFlow::Node node) { this.isSource(node) }
100-
101-
override predicate isSanitizer(DataFlow::Node node) {
81+
predicate isBarrier(DataFlow::Node node) {
10282
node.asExpr().(Call).getTarget().getUnspecifiedType() instanceof ArithmeticType
10383
or
10484
exists(LoadInstruction load, Variable checkedVar |
@@ -107,32 +87,19 @@ class TaintedPathConfiguration extends TaintTracking::Configuration {
10787
hasUpperBoundsCheck(checkedVar)
10888
)
10989
}
110-
111-
predicate hasFilteredFlowPath(DataFlow::PathNode source, DataFlow::PathNode sink) {
112-
this.hasFlowPath(source, sink) and
113-
// The use of `isUserInput` in `isSink` in combination with `asSourceExpr` causes
114-
// duplicate results. Filter these duplicates. The proper solution is to switch to
115-
// using `LocalFlowSource` and `RemoteFlowSource`, but this currently only supports
116-
// a subset of the cases supported by `isUserInput`.
117-
not exists(DataFlow::PathNode source2 |
118-
this.hasFlowPath(source2, sink) and
119-
asSourceExpr(source.getNode()) = asSourceExpr(source2.getNode())
120-
|
121-
not exists(source.getNode().asConvertedExpr()) and exists(source2.getNode().asConvertedExpr())
122-
)
123-
}
12490
}
12591

92+
module TaintedPath = TaintTracking::Make<TaintedPathConfiguration>;
93+
12694
from
127-
FileFunction fileFunction, Expr taintedArg, Expr taintSource, TaintedPathConfiguration cfg,
128-
DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode, string taintCause, string callChain
95+
FileFunction fileFunction, Expr taintedArg, FlowSource taintSource,
96+
TaintedPath::PathNode sourceNode, TaintedPath::PathNode sinkNode, string callChain
12997
where
13098
not isExcluded(taintedArg, IO3Package::doNotPerformFileOperationsOnDevicesQuery()) and
131-
taintedArg = asSinkExpr(sinkNode.getNode()) and
99+
taintedArg = sinkNode.getNode().asIndirectArgument() and
132100
fileFunction.outermostWrapperFunctionCall(taintedArg, callChain) and
133-
cfg.hasFilteredFlowPath(sourceNode, sinkNode) and
134-
taintSource = asSourceExpr(sourceNode.getNode()) and
135-
isUserInput(taintSource, taintCause)
101+
TaintedPath::hasFlowPath(sourceNode, sinkNode) and
102+
taintSource = sourceNode.getNode()
136103
select taintedArg, sourceNode, sinkNode,
137104
"This argument to a file access function is derived from $@ and then passed to " + callChain + ".",
138-
taintSource, "user input (" + taintCause + ")"
105+
taintSource, "user input (" + taintSource.getSourceType() + ")"

c/cert/test/rules/FIO32-C/DoNotPerformFileOperationsOnDevices.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ nodes
88
| test.c:46:29:46:37 | file_name indirection | semmle.label | file_name indirection |
99
subpaths
1010
#select
11-
| test.c:21:8:21:16 | file_name | test.c:20:15:20:23 | scanf output argument | test.c:21:8:21:16 | file_name indirection | This argument to a file access function is derived from $@ and then passed to func(file_name), which calls fopen((unnamed parameter 0)). | test.c:20:15:20:23 | file_name | user input (scanf) |
12-
| test.c:46:29:46:37 | file_name | test.c:45:15:45:23 | scanf output argument | test.c:46:29:46:37 | file_name indirection | This argument to a file access function is derived from $@ and then passed to CreateFile(lpFileName). | test.c:45:15:45:23 | file_name | user input (scanf) |
11+
| test.c:21:8:21:16 | file_name | test.c:20:15:20:23 | scanf output argument | test.c:21:8:21:16 | file_name indirection | This argument to a file access function is derived from $@ and then passed to func(file_name), which calls fopen((unnamed parameter 0)). | test.c:20:15:20:23 | scanf output argument | user input (value read by scanf) |
12+
| test.c:46:29:46:37 | file_name | test.c:45:15:45:23 | scanf output argument | test.c:46:29:46:37 | file_name indirection | This argument to a file access function is derived from $@ and then passed to CreateFile(lpFileName). | test.c:45:15:45:23 | scanf output argument | user input (value read by scanf) |
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- `FIO32-C` - `DoNotPerformFileOperationsOnDevices.ql`:
2+
- The query was updated to work with the latest version of the dataflow library.

0 commit comments

Comments
 (0)