Skip to content

Commit ae6c503

Browse files
committed
C++: Add more indirections in models.
1 parent 6165623 commit ae6c503

28 files changed

Lines changed: 368 additions & 234 deletions

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ private class ReallocAllocationFunction extends AllocationFunction, DataFlowFunc
4545
override int getReallocPtrArg() { result = reallocArg }
4646

4747
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
48-
input.isParameterDeref(this.getReallocPtrArg()) and output.isReturnValueDeref()
48+
exists(int indirectionIndex |
49+
input.isParameterDeref(this.getReallocPtrArg(), indirectionIndex) and
50+
output.isReturnValueDeref(indirectionIndex)
51+
)
4952
}
5053
}
5154

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectF
1212
GetDelimFunction() { this.hasGlobalName(["getdelim", "getwdelim", "__getdelim"]) }
1313

1414
override predicate hasTaintFlow(FunctionInput i, FunctionOutput o) {
15-
i.isParameter(3) and o.isParameterDeref(0)
15+
i.isParameter(3) and o.isParameterDeref(0, 2)
1616
}
1717

18-
override predicate isPartialWrite(FunctionOutput o) { o.isParameterDeref(3) }
18+
override predicate isPartialWrite(FunctionOutput o) { o.isParameterDeref(0, 2) }
1919

2020
override predicate parameterNeverEscapes(int index) { index = [0, 1, 3] }
2121

@@ -38,7 +38,7 @@ private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectF
3838
}
3939

4040
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
41-
output.isParameterDeref(0) and
41+
output.isParameterDeref(0, 2) and
4242
description = "string read by " + this.getName()
4343
}
4444
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ private class FgetsFunction extends DataFlowFunction, TaintFunction, ArrayFuncti
3030
override predicate isPartialWrite(FunctionOutput output) { output.isParameterDeref(2) }
3131

3232
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
33-
input.isParameter(2) and
33+
input.isParameterDeref(2) and
3434
output.isParameterDeref(0)
3535
}
3636

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ private class IdentityFunction extends DataFlowFunction, SideEffectFunction, Ali
3131
// These functions simply return the argument value.
3232
input.isParameter(0) and output.isReturnValue()
3333
or
34-
input.isParameterDeref(0) and output.isReturnValueDeref()
34+
exists(int indirectionIndex |
35+
input.isParameterDeref(0, indirectionIndex) and output.isReturnValueDeref(indirectionIndex)
36+
)
3537
}
3638
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ private class Getaddrinfo extends TaintFunction, ArrayFunction, RemoteFlowSource
151151

152152
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
153153
input.isParameterDeref([0 .. 2]) and
154-
output.isParameterDeref(3)
154+
output.isParameterDeref(3, 2)
155155
}
156156

157157
override predicate hasArrayInput(int bufParam) { bufParam in [0, 1] }

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

Lines changed: 84 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,9 @@ private class IteratorCrementNonMemberOperatorModel extends IteratorCrementNonMe
164164
input = getIteratorArgumentInput(this, 0) and
165165
output.isReturnValue()
166166
or
167-
input.isParameterDeref(0) and output.isReturnValueDeref()
167+
exists(int indirectionIndex |
168+
input.isParameterDeref(0, indirectionIndex) and output.isReturnValueDeref(indirectionIndex)
169+
)
168170
}
169171

170172
override predicate hasOnlySpecificReadSideEffects() { any() }
@@ -205,16 +207,21 @@ private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOp
205207
input.isQualifierAddress() and
206208
output.isReturnValue()
207209
or
208-
input.isReturnValueDeref() and
209-
output.isQualifierObject()
210-
or
211-
input.isQualifierObject() and
212-
output.isReturnValueDeref()
210+
exists(int indirectionIndex |
211+
// reverse flow
212+
input.isReturnValueDeref(indirectionIndex) and
213+
output.isQualifierObject(indirectionIndex)
214+
or
215+
input.isQualifierObject(indirectionIndex) and
216+
output.isReturnValueDeref(indirectionIndex)
217+
)
213218
}
214219

215220
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
216-
input.isQualifierObject() and
217-
output.isReturnValueDeref()
221+
exists(int indirectionIndex |
222+
input.isQualifierObject(indirectionIndex) and
223+
output.isReturnValueDeref(indirectionIndex)
224+
)
218225
}
219226

220227
override predicate hasOnlySpecificReadSideEffects() { any() }
@@ -286,8 +293,11 @@ private class IteratorBinaryArithmeticMemberOperatorModel extends IteratorBinary
286293
TaintFunction
287294
{
288295
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
289-
input.isQualifierObject() and
290-
output.isReturnValue()
296+
exists(int indirectionIndex | input.isQualifierObject(indirectionIndex) |
297+
output.isReturnValueDeref(indirectionIndex)
298+
or
299+
output.isReturnValue()
300+
)
291301
}
292302
}
293303

@@ -346,15 +356,23 @@ private class IteratorAssignArithmeticNonMemberOperatorModel extends IteratorAss
346356
}
347357

348358
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
349-
input.isParameterDeref(0) and output.isReturnValueDeref()
350-
or
351-
// reverse flow from returned reference to the object referenced by the first parameter
352-
input.isReturnValueDeref() and
353-
output.isParameterDeref(0)
354-
or
355-
(input.isParameter(1) or input.isParameterDeref(1)) and
356-
output.isParameterDeref(0)
359+
exists(int indirectionIndex |
360+
input.isParameterDeref(0, indirectionIndex) and output.isReturnValueDeref(indirectionIndex)
361+
or
362+
// reverse flow from returned reference to the object referenced by the first parameter
363+
input.isReturnValueDeref(indirectionIndex) and
364+
output.isParameterDeref(0, indirectionIndex)
365+
or
366+
(
367+
input.isParameter(1) and indirectionIndex = 0
368+
or
369+
input.isParameterDeref(1, indirectionIndex)
370+
) and
371+
output.isParameterDeref(0, indirectionIndex + 1)
372+
)
357373
}
374+
375+
override predicate isPartialWrite(FunctionOutput output) { output.isParameterDeref(0, _) }
358376
}
359377

360378
/**
@@ -378,16 +396,25 @@ private class IteratorAssignArithmeticMemberOperatorModel extends IteratorAssign
378396
}
379397

380398
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
381-
input.isQualifierObject() and
382-
output.isReturnValueDeref()
383-
or
384-
// reverse flow from returned reference to the qualifier
385-
input.isReturnValueDeref() and
386-
output.isQualifierObject()
387-
or
388-
(input.isParameter(0) or input.isParameterDeref(0)) and
389-
output.isQualifierObject()
399+
exists(int indirectionIndex |
400+
input.isParameterDeref(0, indirectionIndex) and output.isReturnValueDeref(indirectionIndex)
401+
or
402+
input.isQualifierObject(indirectionIndex) and output.isReturnValueDeref(indirectionIndex)
403+
or
404+
// reverse flow from returned reference to the object referenced by the first parameter
405+
input.isReturnValueDeref(indirectionIndex) and
406+
output.isQualifierObject(indirectionIndex)
407+
or
408+
(
409+
input.isParameter(0) and indirectionIndex = 0
410+
or
411+
input.isParameterDeref(0, indirectionIndex)
412+
) and
413+
output.isQualifierObject(indirectionIndex + 1)
414+
)
390415
}
416+
417+
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject(_) }
391418
}
392419

393420
/**
@@ -414,11 +441,14 @@ class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunc
414441
}
415442

416443
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
417-
input.isQualifierObject() and
418-
output.isReturnValue()
419-
or
420-
input.isReturnValueDeref() and
421-
output.isQualifierObject()
444+
exists(int indirectionIndex |
445+
input.isQualifierObject(indirectionIndex) and
446+
(output.isReturnValueDeref(indirectionIndex) or output.isReturnValue())
447+
or
448+
// reverse flow
449+
input.isReturnValueDeref(indirectionIndex) and
450+
output.isQualifierObject(indirectionIndex)
451+
)
422452
}
423453

424454
override predicate parameterNeverEscapes(int index) { index = -1 }
@@ -454,8 +484,10 @@ private class IteratorPointerDereferenceNonMemberOperatorModel extends IteratorP
454484
input = getIteratorArgumentInput(this, 0) and
455485
output.isReturnValue()
456486
or
457-
input.isReturnValueDeref() and
458-
output.isParameterDeref(0)
487+
exists(int indirectionIndex |
488+
input.isReturnValueDeref(indirectionIndex) and
489+
output.isParameterDeref(0, indirectionIndex)
490+
)
459491
}
460492

461493
override predicate parameterNeverEscapes(int index) { index = 0 }
@@ -488,8 +520,10 @@ private class IteratorFieldMemberOperator extends Operator, TaintFunction {
488520
IteratorFieldMemberOperator() { this.getClassAndName("operator->") instanceof Iterator }
489521

490522
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
491-
input.isQualifierObject() and
492-
output.isReturnValue()
523+
exists(int indirectionIndex |
524+
input.isQualifierObject(indirectionIndex) and
525+
output.isReturnValueDeref(indirectionIndex) // TODO
526+
)
493527
}
494528
}
495529

@@ -502,8 +536,10 @@ private class IteratorArrayMemberOperator extends MemberFunction, TaintFunction,
502536
IteratorArrayMemberOperator() { this.getClassAndName("operator[]") instanceof Iterator }
503537

504538
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
505-
input.isQualifierObject() and
506-
output.isReturnValue()
539+
exists(int indirectionIndex |
540+
input.isQualifierObject(indirectionIndex) and
541+
output.isReturnValueDeref(indirectionIndex) // TODO
542+
)
507543
}
508544
}
509545

@@ -595,8 +631,11 @@ private class IteratorAssignmentMemberOperatorModel extends IteratorAssignmentMe
595631
TaintFunction, SideEffectFunction, AliasFunction
596632
{
597633
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
598-
(input.isParameterDeref(0) or input.isParameter(0)) and
599-
output.isQualifierObject()
634+
exists(int indirectionIndex | output.isQualifierObject(indirectionIndex + 1) |
635+
input.isParameterDeref(0, indirectionIndex)
636+
or
637+
input.isParameter(0) and indirectionIndex = 0
638+
)
600639
}
601640

602641
override predicate hasOnlySpecificReadSideEffects() { any() }
@@ -669,8 +708,11 @@ private class BeginOrEndFunctionModels extends BeginOrEndFunction, TaintFunction
669708
GetIteratorFunction, AliasFunction, SideEffectFunction
670709
{
671710
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
672-
input.isQualifierObject() and
673-
output.isReturnValue()
711+
exists(int indirectionIndex | input.isQualifierObject(indirectionIndex) |
712+
// output.isReturnValue()
713+
// or
714+
output.isReturnValueDeref(indirectionIndex) // TODO
715+
)
674716
}
675717

676718
override predicate getsIterator(FunctionInput input, FunctionOutput output) {

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

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,14 @@ private class MoveConstructorModel extends MoveConstructor, DataFlowFunction {
6565
private class CopyAssignmentOperatorModel extends CopyAssignmentOperator, TaintFunction {
6666
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
6767
// taint flow from argument to self
68-
input.isParameterDeref(0) and
69-
output.isQualifierObject()
70-
or
71-
// taint flow from argument to return value
72-
input.isParameterDeref(0) and
73-
output.isReturnValueDeref()
68+
exists(int indirectionIndex |
69+
input.isParameterDeref(0, indirectionIndex) and
70+
output.isQualifierObject(indirectionIndex)
71+
or
72+
// taint flow from argument to return value
73+
input.isParameterDeref(0, indirectionIndex) and
74+
output.isReturnValueDeref(indirectionIndex)
75+
)
7476
// TODO: it would be more accurate to model copy assignment as data flow
7577
}
7678
}
@@ -81,12 +83,14 @@ private class CopyAssignmentOperatorModel extends CopyAssignmentOperator, TaintF
8183
private class MoveAssignmentOperatorModel extends MoveAssignmentOperator, TaintFunction {
8284
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
8385
// taint flow from argument to self
84-
input.isParameterDeref(0) and
85-
output.isQualifierObject()
86-
or
87-
// taint flow from argument to return value
88-
input.isParameterDeref(0) and
89-
output.isReturnValueDeref()
86+
exists(int indirectionIndex |
87+
input.isParameterDeref(0, indirectionIndex) and
88+
output.isQualifierObject(indirectionIndex)
89+
or
90+
// taint flow from argument to return value
91+
input.isParameterDeref(0, indirectionIndex) and
92+
output.isReturnValueDeref(indirectionIndex)
93+
)
9094
// TODO: it would be more accurate to model move assignment as data flow
9195
}
9296
}

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,13 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
5353
override predicate hasArrayOutput(int bufParam) { bufParam = this.getParamDest() }
5454

5555
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
56-
input.isParameterDeref(this.getParamSrc()) and
57-
output.isParameterDeref(this.getParamDest())
58-
or
59-
input.isParameterDeref(this.getParamSrc()) and
60-
output.isReturnValueDeref()
56+
exists(int indirectionIndex |
57+
input.isParameterDeref(this.getParamSrc(), indirectionIndex) and
58+
output.isParameterDeref(this.getParamDest(), indirectionIndex)
59+
or
60+
input.isParameterDeref(this.getParamSrc(), indirectionIndex) and
61+
output.isReturnValueDeref(indirectionIndex)
62+
)
6163
or
6264
input.isParameter(this.getParamDest()) and
6365
output.isReturnValue()

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@ abstract private class ScanfFunctionModel extends ArrayFunction, TaintFunction,
4040
int getArgsStartPosition() { result = this.getNumberOfParameters() }
4141

4242
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
43-
input.isParameterDeref(this.(ScanfFunction).getInputParameterIndex()) and
44-
output.isParameterDeref(any(int i | i >= this.getArgsStartPosition()))
43+
exists(int indirectionIndex |
44+
input.isParameterDeref(this.(ScanfFunction).getInputParameterIndex(), indirectionIndex) and
45+
output.isParameterDeref(any(int i | i >= this.getArgsStartPosition()), indirectionIndex)
46+
)
4547
}
4648

4749
override predicate parameterNeverEscapes(int index) {

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

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,17 @@ private class PointerUnwrapperFunction extends MemberFunction, TaintFunction, Da
3838
}
3939

4040
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
41-
input.isReturnValueDeref() and
42-
output.isQualifierObject()
41+
exists(int indirectionIndex |
42+
input.isReturnValueDeref(indirectionIndex) and
43+
output.isQualifierObject(indirectionIndex)
44+
)
4345
}
4446

4547
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
46-
input.isQualifierObject() and output.isReturnValue()
48+
exists(int indirectionIndex |
49+
input.isQualifierObject(indirectionIndex + 1) and
50+
output.isReturnValueDeref(indirectionIndex)
51+
)
4752
}
4853

4954
override predicate hasOnlySpecificReadSideEffects() { any() }
@@ -75,11 +80,16 @@ private class MakeUniqueOrShared extends TaintFunction {
7580
// since these just take a size argument, which we don't want to propagate taint through.
7681
not this.isArray() and
7782
(
78-
input.isParameter([0 .. this.getNumberOfParameters() - 1])
83+
input.isParameter([0 .. this.getNumberOfParameters() - 1]) and
84+
output.isReturnValue()
7985
or
80-
input.isParameterDeref([0 .. this.getNumberOfParameters() - 1])
81-
) and
82-
output.isReturnValue()
86+
exists(int indirectionIndex | output.isReturnValueDeref(indirectionIndex) |
87+
input.isParameterDeref([0 .. this.getNumberOfParameters() - 1], indirectionIndex - 1)
88+
or
89+
input.isParameter([0 .. this.getNumberOfParameters() - 1]) and
90+
indirectionIndex = 1
91+
)
92+
)
8393
}
8494

8595
/**

0 commit comments

Comments
 (0)