Skip to content

Commit 7e9bf2a

Browse files
committed
C++: Add a model for 'partial updating' and extend models appropriately.
1 parent 24a63ae commit 7e9bf2a

File tree

15 files changed

+118
-30
lines changed

15 files changed

+118
-30
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ private import DataFlowImplCommon as DataFlowImplCommon
55
private import semmle.code.cpp.models.interfaces.Allocation as Alloc
66
private import semmle.code.cpp.models.interfaces.DataFlow as DataFlow
77
private import semmle.code.cpp.models.interfaces.Taint as Taint
8+
private import semmle.code.cpp.models.interfaces.PartialFlow as PartialFlow
89
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs as FIO
910
private import semmle.code.cpp.ir.internal.IRCppLanguage
1011
private import semmle.code.cpp.ir.dataflow.internal.ModelUtil
@@ -816,10 +817,15 @@ private predicate inOut(FIO::FunctionInput input, FIO::FunctionOutput output) {
816817
* flows to `n`).
817818
*/
818819
private predicate modeledFlowBarrier(Node n) {
819-
exists(FIO::FunctionInput input, FIO::FunctionOutput output, CallInstruction call |
820+
exists(
821+
FIO::FunctionInput input, FIO::FunctionOutput output, CallInstruction call,
822+
PartialFlow::PartialFlowFunction partialFlowFunc
823+
|
820824
n = callInput(call, input) and
821825
inOut(input, output) and
822-
exists(callOutput(call, output))
826+
exists(callOutput(call, output)) and
827+
partialFlowFunc = call.getStaticCallTarget() and
828+
not partialFlowFunc.isPartialWrite(output)
823829
|
824830
call.getStaticCallTarget().(DataFlow::DataFlowFunction).hasDataFlow(_, output)
825831
or

cpp/ql/lib/semmle/code/cpp/models/implementations/GetDelim.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectF
1515
i.isParameter(3) and o.isParameterDeref(0)
1616
}
1717

18+
override predicate isPartialWrite(FunctionOutput o) { o.isParameterDeref(3) }
19+
1820
override predicate parameterNeverEscapes(int index) { index = [0, 1, 3] }
1921

2022
override predicate parameterEscapesOnlyViaReturn(int index) { none() }

cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ private class FgetsFunction extends DataFlowFunction, TaintFunction, ArrayFuncti
2727
output.isReturnValue()
2828
}
2929

30+
override predicate isPartialWrite(FunctionOutput output) { output.isParameterDeref(2) }
31+
3032
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
3133
input.isParameter(2) and
3234
output.isParameterDeref(0)

cpp/ql/lib/semmle/code/cpp/models/implementations/Inet.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ private class InetAton extends TaintFunction, ArrayFunction {
2020
output.isParameterDeref(1)
2121
}
2222

23+
override predicate isPartialWrite(FunctionOutput output) { output.isParameterDeref(1) }
24+
2325
override predicate hasArrayInput(int bufParam) { bufParam = 0 }
2426

2527
override predicate hasArrayOutput(int bufParam) { bufParam = 1 }

cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ private class StdSequenceContainerData extends TaintFunction {
118118
input.isReturnValueDeref() and
119119
output.isQualifierObject()
120120
}
121+
122+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
121123
}
122124

123125
/**
@@ -147,6 +149,8 @@ private class StdSequenceContainerPushModel extends StdSequenceContainerPush, Ta
147149
input.isParameterDeref(0) and
148150
output.isQualifierObject()
149151
}
152+
153+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
150154
}
151155

152156
/**
@@ -207,6 +211,8 @@ private class StdSequenceContainerInsertModel extends StdSequenceContainerInsert
207211
output.isReturnValue()
208212
)
209213
}
214+
215+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
210216
}
211217

212218
/**
@@ -263,6 +269,8 @@ private class StdSequenceContainerAt extends TaintFunction {
263269
input.isReturnValueDeref() and
264270
output.isQualifierObject()
265271
}
272+
273+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
266274
}
267275

268276
/**
@@ -297,6 +305,8 @@ private class StdSequenceEmplaceModel extends StdSequenceEmplace, TaintFunction
297305
output.isReturnValue()
298306
)
299307
}
308+
309+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
300310
}
301311

302312
/**
@@ -335,6 +345,8 @@ private class StdSequenceEmplaceBackModel extends StdSequenceEmplaceBack, TaintF
335345
input.isParameterDeref([0 .. this.getNumberOfParameters() - 1]) and
336346
output.isQualifierObject()
337347
}
348+
349+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
338350
}
339351

340352
/**

cpp/ql/lib/semmle/code/cpp/models/implementations/StdMap.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
import semmle.code.cpp.models.interfaces.Taint
6+
import semmle.code.cpp.models.interfaces.DataFlow
67
import semmle.code.cpp.models.interfaces.Iterator
78

89
/**
@@ -53,6 +54,8 @@ private class StdMapInsert extends TaintFunction {
5354
output.isReturnValue()
5455
)
5556
}
57+
58+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
5659
}
5760

5861
/**
@@ -75,6 +78,8 @@ private class StdMapEmplace extends TaintFunction {
7578
input.isQualifierObject() and
7679
output.isReturnValue()
7780
}
81+
82+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
7883
}
7984

8085
/**
@@ -102,6 +107,8 @@ private class StdMapTryEmplace extends TaintFunction {
102107
input.isQualifierObject() and
103108
output.isReturnValue()
104109
}
110+
111+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
105112
}
106113

107114
/**
@@ -115,6 +122,8 @@ private class StdMapMerge extends TaintFunction {
115122
input.isParameterDeref(0) and
116123
output.isQualifierObject()
117124
}
125+
126+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
118127
}
119128

120129
/**
@@ -132,6 +141,8 @@ private class StdMapAt extends TaintFunction {
132141
input.isReturnValueDeref() and
133142
output.isQualifierObject()
134143
}
144+
145+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
135146
}
136147

137148
/**

cpp/ql/lib/semmle/code/cpp/models/implementations/StdSet.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ private class StdSetInsert extends TaintFunction {
6161
output.isReturnValue()
6262
)
6363
}
64+
65+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
6466
}
6567

6668
/**
@@ -82,6 +84,8 @@ private class StdSetEmplace extends TaintFunction {
8284
input.isQualifierObject() and
8385
output.isReturnValue()
8486
}
87+
88+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
8589
}
8690

8791
/**
@@ -95,6 +99,8 @@ private class StdSetMerge extends TaintFunction {
9599
input.isParameterDeref(0) and
96100
output.isQualifierObject()
97101
}
102+
103+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
98104
}
99105

100106
/**

cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ private class StdStringDataModel extends StdStringData, StdStringTaintFunction {
129129
input.isReturnValueDeref() and
130130
output.isQualifierObject()
131131
}
132+
133+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
132134
}
133135

134136
/**
@@ -142,6 +144,8 @@ private class StdStringPush extends StdStringTaintFunction {
142144
input.isParameter(0) and
143145
output.isQualifierObject()
144146
}
147+
148+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
145149
}
146150

147151
/**
@@ -204,6 +208,8 @@ private class StdStringAppend extends StdStringTaintFunction {
204208
input.isReturnValueDeref() and
205209
output.isQualifierObject()
206210
}
211+
212+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
207213
}
208214

209215
/**
@@ -237,6 +243,8 @@ private class StdStringInsert extends StdStringTaintFunction {
237243
input.isReturnValueDeref() and
238244
output.isQualifierObject()
239245
}
246+
247+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
240248
}
241249

242250
/**
@@ -305,6 +313,8 @@ private class StdStringAt extends StdStringTaintFunction {
305313
input.isReturnValueDeref() and
306314
output.isQualifierObject()
307315
}
316+
317+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
308318
}
309319

310320
/**
@@ -338,6 +348,8 @@ private class StdIStreamIn extends DataFlowFunction, TaintFunction {
338348
input.isReturnValueDeref() and
339349
output.isQualifierObject()
340350
}
351+
352+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
341353
}
342354

343355
/**
@@ -358,6 +370,8 @@ private class StdIStreamInNonMember extends DataFlowFunction, TaintFunction {
358370
output.isReturnValueDeref()
359371
}
360372

373+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
374+
361375
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
362376
// flow from first parameter to second parameter
363377
input.isParameterDeref(0) and
@@ -403,6 +417,8 @@ private class StdIStreamRead extends DataFlowFunction, TaintFunction {
403417
output.isReturnValueDeref()
404418
}
405419

420+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
421+
406422
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
407423
// flow from qualifier to first parameter
408424
input.isQualifierObject() and
@@ -442,6 +458,8 @@ private class StdIStreamPutBack extends DataFlowFunction, TaintFunction {
442458
output.isReturnValueDeref()
443459
}
444460

461+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
462+
445463
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
446464
// flow from first parameter (value or pointer) to qualifier
447465
input.isParameter(0) and
@@ -478,6 +496,8 @@ private class StdIStreamGetLine extends DataFlowFunction, TaintFunction {
478496
output.isReturnValueDeref()
479497
}
480498

499+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
500+
481501
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
482502
// flow from qualifier to first parameter
483503
input.isQualifierObject() and
@@ -540,6 +560,8 @@ private class StdOStreamOut extends DataFlowFunction, TaintFunction {
540560
output.isReturnValueDeref()
541561
}
542562

563+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
564+
543565
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
544566
// flow from first parameter (value or pointer) to qualifier
545567
input.isParameter(0) and
@@ -579,6 +601,8 @@ private class StdOStreamOutNonMember extends DataFlowFunction, TaintFunction {
579601
output.isReturnValueDeref()
580602
}
581603

604+
override predicate isPartialWrite(FunctionOutput output) { output.isParameterDeref(0) }
605+
582606
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
583607
// flow from second parameter to first parameter
584608
input.isParameterDeref(1) and
@@ -672,6 +696,8 @@ private class StdStreamFunction extends DataFlowFunction, TaintFunction {
672696
output.isReturnValueDeref()
673697
}
674698

699+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
700+
675701
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
676702
// reverse flow from returned reference to the qualifier
677703
input.isReturnValueDeref() and

cpp/ql/lib/semmle/code/cpp/models/implementations/Strcrement.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ private class Strcrement extends ArrayFunction, TaintFunction, SideEffectFunctio
3636
input.isParameter(index) and output.isReturnValue()
3737
or
3838
input.isParameterDeref(index) and output.isReturnValueDeref()
39+
or
40+
input.isParameterDeref(index) and output.isParameterDeref(index)
3941
)
4042
}
4143

cpp/ql/lib/semmle/code/cpp/models/interfaces/DataFlow.qll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import semmle.code.cpp.Function
1111
import FunctionInputsAndOutputs
1212
import semmle.code.cpp.models.Models
13+
import PartialFlow
1314

1415
/**
1516
* A library function for which a value is or may be copied from a parameter
@@ -18,7 +19,7 @@ import semmle.code.cpp.models.Models
1819
* Note that this does not include partial copying of values or partial writes
1920
* to destinations; that is covered by `TaintModel.qll`.
2021
*/
21-
abstract class DataFlowFunction extends Function {
22+
abstract class DataFlowFunction extends PartialFlowFunction {
2223
/**
2324
* Holds if data can be copied from the argument, qualifier, or buffer
2425
* represented by `input` to the return value or buffer represented by

0 commit comments

Comments
 (0)