Skip to content

Commit 4363a8e

Browse files
committed
C++: Update leap year queries with DataFlow::ConfigSig
1 parent e65ba13 commit 4363a8e

File tree

4 files changed

+103
-16
lines changed

4 files changed

+103
-16
lines changed

cpp/ql/src/Likely Bugs/Leap Year/Adding365DaysPerYear.ql

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
import cpp
1515
import LeapYear
1616

17-
from Expr source, Expr sink, PossibleYearArithmeticOperationCheckConfiguration config
18-
where config.hasFlow(DataFlow::exprNode(source), DataFlow::exprNode(sink))
17+
from Expr source, Expr sink
18+
where
19+
PossibleYearArithmeticOperationCheckFlow::hasFlow(DataFlow::exprNode(source),
20+
DataFlow::exprNode(sink))
1921
select sink,
2022
"An arithmetic operation $@ that uses a constant value of 365 ends up modifying this date/time, without considering leap year scenarios.",
2123
source, source.toString()

cpp/ql/src/Likely Bugs/Leap Year/LeapYear.qll

Lines changed: 89 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,10 @@ class ChecksForLeapYearFunctionCall extends FunctionCall {
206206
}
207207

208208
/**
209-
* `DataFlow::Configuration` for finding a variable access that would flow into
209+
* Data flow configuration for finding a variable access that would flow into
210210
* a function call that includes an operation to check for leap year.
211211
*/
212-
class LeapYearCheckConfiguration extends DataFlow::Configuration {
212+
deprecated class LeapYearCheckConfiguration extends DataFlow::Configuration {
213213
LeapYearCheckConfiguration() { this = "LeapYearCheckConfiguration" }
214214

215215
override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof VariableAccess }
@@ -220,9 +220,24 @@ class LeapYearCheckConfiguration extends DataFlow::Configuration {
220220
}
221221

222222
/**
223-
* `DataFlow::Configuration` for finding an operation with hardcoded 365 that will flow into a `FILEINFO` field.
223+
* Data flow configuration for finding a variable access that would flow into
224+
* a function call that includes an operation to check for leap year.
225+
*/
226+
private module LeapYearCheckConfiguration implements DataFlow::ConfigSig {
227+
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof VariableAccess }
228+
229+
predicate isSink(DataFlow::Node sink) {
230+
exists(ChecksForLeapYearFunctionCall fc | sink.asExpr() = fc.getAnArgument())
231+
}
232+
}
233+
234+
module LeapYearCheckFlow = DataFlow::Make<LeapYearCheckConfiguration>;
235+
236+
/**
237+
* Data flow configuration for finding an operation with hardcoded 365 that will flow into
238+
* a `FILEINFO` field.
224239
*/
225-
class FiletimeYearArithmeticOperationCheckConfiguration extends DataFlow::Configuration {
240+
deprecated class FiletimeYearArithmeticOperationCheckConfiguration extends DataFlow::Configuration {
226241
FiletimeYearArithmeticOperationCheckConfiguration() {
227242
this = "FiletimeYearArithmeticOperationCheckConfiguration"
228243
}
@@ -245,10 +260,36 @@ class FiletimeYearArithmeticOperationCheckConfiguration extends DataFlow::Config
245260
}
246261
}
247262

263+
/**
264+
* Data flow configuration for finding an operation with hardcoded 365 that will flow into
265+
* a `FILEINFO` field.
266+
*/
267+
private module FiletimeYearArithmeticOperationCheckConfiguration implements DataFlow::ConfigSig {
268+
predicate isSource(DataFlow::Node source) {
269+
exists(Expr e, Operation op | e = source.asExpr() |
270+
op.getAChild*().getValue().toInt() = 365 and
271+
op.getAChild*() = e
272+
)
273+
}
274+
275+
predicate isSink(DataFlow::Node sink) {
276+
exists(StructLikeClass dds, FieldAccess fa, AssignExpr aexpr, Expr e | e = sink.asExpr() |
277+
dds instanceof PackedTimeType and
278+
fa.getQualifier().getUnderlyingType() = dds and
279+
fa.isModified() and
280+
aexpr.getAChild() = fa and
281+
aexpr.getChild(1).getAChild*() = e
282+
)
283+
}
284+
}
285+
286+
module FiletimeYearArithmeticOperationCheckFlow =
287+
DataFlow::Make<FiletimeYearArithmeticOperationCheckConfiguration>;
288+
248289
/**
249290
* Taint configuration for finding an operation with hardcoded 365 that will flow into any known date/time field.
250291
*/
251-
class PossibleYearArithmeticOperationCheckConfiguration extends TaintTracking::Configuration {
292+
deprecated class PossibleYearArithmeticOperationCheckConfiguration extends TaintTracking::Configuration {
252293
PossibleYearArithmeticOperationCheckConfiguration() {
253294
this = "PossibleYearArithmeticOperationCheckConfiguration"
254295
}
@@ -288,3 +329,46 @@ class PossibleYearArithmeticOperationCheckConfiguration extends TaintTracking::C
288329
)
289330
}
290331
}
332+
333+
/**
334+
* Taint configuration for finding an operation with hardcoded 365 that will flow into any known date/time field.
335+
*/
336+
private module PossibleYearArithmeticOperationCheckConfiguration implements DataFlow::ConfigSig {
337+
predicate isSource(DataFlow::Node source) {
338+
exists(Operation op | op = source.asConvertedExpr() |
339+
op.getAChild*().getValue().toInt() = 365 and
340+
(
341+
not op.getParent() instanceof Expr or
342+
op.getParent() instanceof Assignment
343+
)
344+
)
345+
}
346+
347+
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
348+
// flow from anything on the RHS of an assignment to a time/date structure to that
349+
// assignment.
350+
exists(StructLikeClass dds, FieldAccess fa, Assignment aexpr, Expr e |
351+
e = node1.asExpr() and
352+
fa = node2.asExpr()
353+
|
354+
(dds instanceof PackedTimeType or dds instanceof UnpackedTimeType) and
355+
fa.getQualifier().getUnderlyingType() = dds and
356+
aexpr.getLValue() = fa and
357+
aexpr.getRValue().getAChild*() = e
358+
)
359+
}
360+
361+
predicate isSink(DataFlow::Node sink) {
362+
exists(StructLikeClass dds, FieldAccess fa, AssignExpr aexpr |
363+
aexpr.getRValue() = sink.asConvertedExpr()
364+
|
365+
(dds instanceof PackedTimeType or dds instanceof UnpackedTimeType) and
366+
fa.getQualifier().getUnderlyingType() = dds and
367+
fa.isModified() and
368+
aexpr.getLValue() = fa
369+
)
370+
}
371+
}
372+
373+
module PossibleYearArithmeticOperationCheckFlow =
374+
TaintTracking::Make<PossibleYearArithmeticOperationCheckConfiguration>;

cpp/ql/src/Likely Bugs/Leap Year/UncheckedLeapYearAfterYearModification.ql

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,18 @@ where
2929
)
3030
or
3131
// If there is a data flow from the variable that was modified to a function that seems to check for leap year
32-
exists(
33-
VariableAccess source, ChecksForLeapYearFunctionCall fc, LeapYearCheckConfiguration config
34-
|
32+
exists(VariableAccess source, ChecksForLeapYearFunctionCall fc |
3533
source = var.getAnAccess() and
36-
config.hasFlow(DataFlow::exprNode(source), DataFlow::exprNode(fc.getAnArgument()))
34+
LeapYearCheckFlow::hasFlow(DataFlow::exprNode(source),
35+
DataFlow::exprNode(fc.getAnArgument()))
3736
)
3837
or
3938
// If there is a data flow from the field that was modified to a function that seems to check for leap year
40-
exists(
41-
VariableAccess vacheck, YearFieldAccess yfacheck, ChecksForLeapYearFunctionCall fc,
42-
LeapYearCheckConfiguration config
43-
|
39+
exists(VariableAccess vacheck, YearFieldAccess yfacheck, ChecksForLeapYearFunctionCall fc |
4440
vacheck = var.getAnAccess() and
4541
yfacheck.getQualifier() = vacheck and
46-
config.hasFlow(DataFlow::exprNode(yfacheck), DataFlow::exprNode(fc.getAnArgument()))
42+
LeapYearCheckFlow::hasFlow(DataFlow::exprNode(yfacheck),
43+
DataFlow::exprNode(fc.getAnArgument()))
4744
)
4845
or
4946
// If there is a successor or predecessor that sets the month = 1
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: deprecated
3+
---
4+
* The `LeapYearCheckConfiguration`, `FiletimeYearArithmeticOperationCheckConfiguration`, and `PossibleYearArithmeticOperationCheckConfiguration` dataflow configurations have been deprecated. Please use `LeapYearCheckFlow`, `FiletimeYearArithmeticOperationCheckFlow` and `PossibleYearArithmeticOperationCheckFlow`.

0 commit comments

Comments
 (0)