Skip to content

Commit 1189665

Browse files
committed
C++: Add barriers to 'cpp/overrun-write'.
1 parent a502bb1 commit 1189665

File tree

3 files changed

+24
-18
lines changed

3 files changed

+24
-18
lines changed

cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import semmle.code.cpp.models.interfaces.Allocation
2020
import semmle.code.cpp.models.interfaces.ArrayFunction
2121
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis
2222
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
23+
import semmle.code.cpp.security.ProductFlowUtils.ProductFlowUtils
2324
import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil
2425
import StringSizeFlow::PathGraph1
2526
import codeql.util.Unit
@@ -109,17 +110,24 @@ module ValidState {
109110

110111
import ValidState
111112

112-
/**
113-
* Holds if `node2` is a dataflow node that represents an addition of two operands `op1`
114-
* and `op2` such that:
115-
* 1. `node1` is the dataflow node that represents `op1`, and
116-
* 2. the value of `op2` can be upper bounded by `delta.`
117-
*/
118-
predicate isAdditionalFlowStep2(DataFlow::Node node1, DataFlow::Node node2, int delta) {
119-
exists(AddInstruction add, Operand op |
120-
add.hasOperands(node1.asOperand(), op) and
121-
semBounded(getSemanticExpr(op.getDef()), any(SemZeroBound zero), delta, true, _) and
122-
node2.asInstruction() = add
113+
module SizeBarrierInput implements SizeBarrierInputSig {
114+
int fieldFlowBranchLimit() { result = 2 }
115+
116+
predicate isSource(DataFlow::Node source) {
117+
exists(int state |
118+
hasSize(_, source, state) and
119+
validState(source, _, state)
120+
)
121+
}
122+
}
123+
124+
predicate isSinkPairImpl(
125+
CallInstruction c, DataFlow::Node bufSink, DataFlow::Node sizeSink, int delta, Expr eBuf
126+
) {
127+
exists(Instruction sizeBound, Instruction sizeInstr |
128+
isSinkPairImpl0(c, bufSink, sizeSink, delta, eBuf, sizeBound, sizeInstr) and
129+
not sizeBound = SizeBarrier<SizeBarrierInput>::getABarrierInstruction(delta) and
130+
not sizeInstr = SizeBarrier<SizeBarrierInput>::getABarrierInstruction(delta)
123131
)
124132
}
125133

@@ -154,6 +162,10 @@ module StringSizeConfig implements ProductFlow::StateConfigSig {
154162
}
155163

156164
predicate isBarrierOut2(DataFlow::Node node) { DataFlow::flowsToBackEdge(node) }
165+
166+
predicate isBarrier2(DataFlow::Node node, FlowState2 state) {
167+
node = SizeBarrier<SizeBarrierInput>::getABarrierNode(state)
168+
}
157169
}
158170

159171
module StringSizeFlow = ProductFlow::GlobalWithState<StringSizeConfig>;

cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ edges
4949
| test.cpp:262:15:262:30 | call to malloc | test.cpp:266:12:266:12 | p | provenance | |
5050
| test.cpp:264:9:264:30 | ... = ... | test.cpp:266:12:266:12 | p | provenance | |
5151
| test.cpp:264:13:264:30 | call to malloc | test.cpp:264:9:264:30 | ... = ... | provenance | |
52-
| test.cpp:271:14:271:27 | new[] | test.cpp:271:14:271:27 | new[] | provenance | |
53-
| test.cpp:271:14:271:27 | new[] | test.cpp:276:12:276:13 | xs | provenance | |
5452
nodes
5553
| test.cpp:16:11:16:21 | **mk_string_t [string] | semmle.label | **mk_string_t [string] |
5654
| test.cpp:18:5:18:7 | *str [post update] [string] | semmle.label | *str [post update] [string] |
@@ -107,9 +105,6 @@ nodes
107105
| test.cpp:264:9:264:30 | ... = ... | semmle.label | ... = ... |
108106
| test.cpp:264:13:264:30 | call to malloc | semmle.label | call to malloc |
109107
| test.cpp:266:12:266:12 | p | semmle.label | p |
110-
| test.cpp:271:14:271:27 | new[] | semmle.label | new[] |
111-
| test.cpp:271:14:271:27 | new[] | semmle.label | new[] |
112-
| test.cpp:276:12:276:13 | xs | semmle.label | xs |
113108
subpaths
114109
| test.cpp:242:22:242:27 | buffer | test.cpp:235:40:235:45 | buffer | test.cpp:235:27:235:31 | *p_str [Return] [string] | test.cpp:242:16:242:19 | set_string output argument [string] |
115110
| test.cpp:242:22:242:27 | buffer | test.cpp:235:40:235:45 | buffer | test.cpp:235:27:235:31 | *p_str [string] | test.cpp:242:16:242:19 | set_string output argument [string] |
@@ -129,4 +124,3 @@ subpaths
129124
| test.cpp:243:5:243:10 | call to memset | test.cpp:241:20:241:38 | call to malloc | test.cpp:243:12:243:21 | string | This write may overflow $@ by 1 element. | test.cpp:243:16:243:21 | string | string |
130125
| test.cpp:250:5:250:10 | call to memset | test.cpp:249:14:249:33 | call to my_alloc | test.cpp:250:12:250:12 | p | This write may overflow $@ by 1 element. | test.cpp:250:12:250:12 | p | p |
131126
| test.cpp:266:5:266:10 | call to memset | test.cpp:262:15:262:30 | call to malloc | test.cpp:266:12:266:12 | p | This write may overflow $@ by 1 element. | test.cpp:266:12:266:12 | p | p |
132-
| test.cpp:276:5:276:10 | call to memset | test.cpp:271:14:271:27 | new[] | test.cpp:276:12:276:13 | xs | This write may overflow $@ by 1 element. | test.cpp:276:12:276:13 | xs | xs |

cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,6 @@ void test8(unsigned size, unsigned src_pos)
273273
src_pos = size;
274274
}
275275
if (src_pos < size - 1) {
276-
memset(xs, 0, src_pos + 1); // GOOD [FALSE POSITIVE]
276+
memset(xs, 0, src_pos + 1); // GOOD
277277
}
278278
}

0 commit comments

Comments
 (0)