Skip to content

Commit 967bbbc

Browse files
committed
C++: Block flow out of sinks that are qualifiers. This removes the new result duplication and keeps the new result.
1 parent c73e6f1 commit 967bbbc

File tree

2 files changed

+11
-27
lines changed

2 files changed

+11
-27
lines changed

cpp/ql/src/Security/CWE/CWE-120/UnboundedWrite.ql

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -52,35 +52,25 @@ predicate isUnboundedWrite(BufferWrite bw) {
5252
* Holds if `e` is a source buffer going into an unbounded write `bw` or a
5353
* qualifier of (a qualifier of ...) such a source.
5454
*/
55-
predicate unboundedWriteSource(Expr e, BufferWrite bw) {
56-
isUnboundedWrite(bw) and e = bw.getASource()
55+
predicate unboundedWriteSource(Expr e, BufferWrite bw, boolean qualifier) {
56+
isUnboundedWrite(bw) and e = bw.getASource() and qualifier = false
5757
or
58-
exists(FieldAccess fa | unboundedWriteSource(fa, bw) and e = fa.getQualifier())
58+
exists(FieldAccess fa | unboundedWriteSource(fa, bw, _) and e = fa.getQualifier()) and
59+
qualifier = true
5960
}
6061

6162
predicate isSource(FS::FlowSource source, string sourceType) { source.getSourceType() = sourceType }
6263

63-
/**
64-
* Holds if `bw` is a `BufferWrite` that reads from `stdin`. In such cases the
65-
* sink is the outgoing argument that is written to.
66-
*
67-
* By factoring these cases out into this predicate we can place an out barrier
68-
* on exactly these sinks in `Config`.
69-
*/
70-
predicate isSinkFromStdIn(DataFlow::Node sink, BufferWrite bw) {
64+
predicate isSink(DataFlow::Node sink, BufferWrite bw, boolean qualifier) {
65+
unboundedWriteSource(sink.asIndirectExpr(), bw, qualifier)
66+
or
7167
// `gets` and `scanf` reads from stdin so there's no real input.
7268
// The `BufferWrite` library models this as the call itself being
7369
// the source. In this case we mark the output argument as being
7470
// the sink so that we report a path where source = sink (because
7571
// the same output argument is also included in `isSource`).
7672
bw.getASource() = bw and
77-
unboundedWriteSource(sink.asDefiningArgument(), bw)
78-
}
79-
80-
predicate isSink(DataFlow::Node sink, BufferWrite bw) {
81-
unboundedWriteSource(sink.asIndirectExpr(), bw)
82-
or
83-
isSinkFromStdIn(sink, bw)
73+
unboundedWriteSource(sink.asDefiningArgument(), bw, qualifier)
8474
}
8575

8676
predicate lessThanOrEqual(IRGuardCondition g, Expr e, boolean branch) {
@@ -95,9 +85,9 @@ predicate lessThanOrEqual(IRGuardCondition g, Expr e, boolean branch) {
9585
module Config implements DataFlow::ConfigSig {
9686
predicate isSource(DataFlow::Node source) { isSource(source, _) }
9787

98-
predicate isSink(DataFlow::Node sink) { isSink(sink, _) }
88+
predicate isSink(DataFlow::Node sink) { isSink(sink, _, _) }
9989

100-
predicate isBarrierOut(DataFlow::Node node) { isSinkFromStdIn(node, _) }
90+
predicate isBarrierOut(DataFlow::Node node) { isSink(node, _, false) }
10191

10292
predicate isBarrier(DataFlow::Node node) {
10393
// Block flow if the node is guarded by any <, <= or = operations.
@@ -127,7 +117,7 @@ from BufferWrite bw, Flow::PathNode source, Flow::PathNode sink, string sourceTy
127117
where
128118
Flow::flowPath(source, sink) and
129119
isSource(source.getNode(), sourceType) and
130-
isSink(sink.getNode(), bw)
120+
isSink(sink.getNode(), bw, _)
131121
select bw, source, sink,
132122
"This '" + bw.getBWDesc() + "' with input from $@ may overflow the destination.",
133123
source.getNode(), sourceType
Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
edges
22
| tests.c:16:26:16:29 | argv indirection | tests.c:28:22:28:28 | access to array indirection |
33
| tests.c:16:26:16:29 | argv indirection | tests.c:29:28:29:34 | access to array indirection |
4-
| tests.c:16:26:16:29 | argv indirection | tests.c:31:15:31:23 | buffer100 indirection |
5-
| tests.c:16:26:16:29 | argv indirection | tests.c:33:21:33:29 | buffer100 indirection |
64
| tests.c:16:26:16:29 | argv indirection | tests.c:34:10:34:16 | access to array indirection |
75
nodes
86
| tests.c:16:26:16:29 | argv indirection | semmle.label | argv indirection |
97
| tests.c:28:22:28:28 | access to array indirection | semmle.label | access to array indirection |
108
| tests.c:29:28:29:34 | access to array indirection | semmle.label | access to array indirection |
11-
| tests.c:31:15:31:23 | buffer100 indirection | semmle.label | buffer100 indirection |
129
| tests.c:31:15:31:23 | scanf output argument | semmle.label | scanf output argument |
13-
| tests.c:33:21:33:29 | buffer100 indirection | semmle.label | buffer100 indirection |
1410
| tests.c:33:21:33:29 | scanf output argument | semmle.label | scanf output argument |
1511
| tests.c:34:10:34:16 | access to array indirection | semmle.label | access to array indirection |
1612
subpaths
1713
#select
1814
| tests.c:28:3:28:9 | call to sprintf | tests.c:16:26:16:29 | argv indirection | tests.c:28:22:28:28 | access to array indirection | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:16:26:16:29 | argv indirection | a command-line argument |
1915
| tests.c:29:3:29:9 | call to sprintf | tests.c:16:26:16:29 | argv indirection | tests.c:29:28:29:34 | access to array indirection | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:16:26:16:29 | argv indirection | a command-line argument |
20-
| tests.c:31:15:31:23 | buffer100 | tests.c:16:26:16:29 | argv indirection | tests.c:31:15:31:23 | buffer100 indirection | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:16:26:16:29 | argv indirection | a command-line argument |
2116
| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | scanf output argument | tests.c:31:15:31:23 | scanf output argument | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | scanf output argument | value read by scanf |
22-
| tests.c:33:21:33:29 | buffer100 | tests.c:16:26:16:29 | argv indirection | tests.c:33:21:33:29 | buffer100 indirection | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:16:26:16:29 | argv indirection | a command-line argument |
2317
| tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | scanf output argument | tests.c:33:21:33:29 | scanf output argument | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:33:21:33:29 | scanf output argument | value read by scanf |
2418
| tests.c:34:25:34:33 | buffer100 | tests.c:16:26:16:29 | argv indirection | tests.c:34:10:34:16 | access to array indirection | This 'sscanf string argument' with input from $@ may overflow the destination. | tests.c:16:26:16:29 | argv indirection | a command-line argument |

0 commit comments

Comments
 (0)