Skip to content

Commit cf8a683

Browse files
Merge branch 'main' into main
2 parents 05137d0 + 434b1b3 commit cf8a683

File tree

512 files changed

+20667
-5221
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

512 files changed

+20667
-5221
lines changed

.github/workflows/ruby-build.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ jobs:
5050
echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH
5151
- name: Install cargo-cross
5252
if: runner.os == 'Linux'
53-
run: cargo install cross --version 0.2.1
53+
run: cargo install cross --version 0.2.5
5454
- uses: ./.github/actions/os-version
5555
id: os_version
5656
- name: Cache entire extractor
@@ -85,7 +85,12 @@ jobs:
8585
# This ensures we don't depend on glibc > 2.17.
8686
- name: Release build (linux)
8787
if: steps.cache-extractor.outputs.cache-hit != 'true' && runner.os == 'Linux'
88-
run: cd extractor && cross build --release
88+
run: |
89+
cd extractor
90+
cross build --release
91+
mv target/x86_64-unknown-linux-gnu/release/extractor target/release/
92+
mv target/x86_64-unknown-linux-gnu/release/autobuilder target/release/
93+
mv target/x86_64-unknown-linux-gnu/release/generator target/release/
8994
- name: Release build (windows and macos)
9095
if: steps.cache-extractor.outputs.cache-hit != 'true' && runner.os != 'Linux'
9196
run: cd extractor && cargo build --release

.github/workflows/ruby-qltest.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on:
44
push:
55
paths:
66
- "ruby/**"
7+
- "shared/**"
78
- .github/workflows/ruby-build.yml
89
- .github/actions/fetch-codeql/action.yml
910
- codeql-workspace.yml
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: fix
3+
---
4+
* Fixed some accidental predicate visibility in the backwards-compatible wrapper for data flow configurations. In particular `DataFlow::hasFlowPath`, `DataFlow::hasFlow`, `DataFlow::hasFlowTo`, and `DataFlow::hasFlowToExpr` were accidentally exposed in a single version.

cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll

Lines changed: 180 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -591,24 +591,6 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
591591
delta = D::fromInt(0) and
592592
(upper = true or upper = false)
593593
or
594-
exists(SemExpr x | e2.(SemAddExpr).hasOperands(e1, x) |
595-
// `x instanceof ConstantIntegerExpr` is covered by valueFlowStep
596-
not x instanceof SemConstantIntegerExpr and
597-
not e1 instanceof SemConstantIntegerExpr and
598-
if strictlyPositiveIntegralExpr(x)
599-
then upper = false and delta = D::fromInt(1)
600-
else
601-
if semPositive(x)
602-
then upper = false and delta = D::fromInt(0)
603-
else
604-
if strictlyNegativeIntegralExpr(x)
605-
then upper = true and delta = D::fromInt(-1)
606-
else
607-
if semNegative(x)
608-
then upper = true and delta = D::fromInt(0)
609-
else none()
610-
)
611-
or
612594
exists(SemExpr x, SemSubExpr sub |
613595
e2 = sub and
614596
sub.getLeftOperand() = e1 and
@@ -1043,13 +1025,193 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
10431025
delta = D::fromFloat(f) and
10441026
if semPositive(e) then f >= 0 else any()
10451027
)
1028+
or
1029+
exists(
1030+
SemBound bLeft, SemBound bRight, D::Delta dLeft, D::Delta dRight, boolean fbeLeft,
1031+
boolean fbeRight, D::Delta odLeft, D::Delta odRight, SemReason rLeft, SemReason rRight
1032+
|
1033+
boundedAddOperand(e, upper, bLeft, false, dLeft, fbeLeft, odLeft, rLeft) and
1034+
boundedAddOperand(e, upper, bRight, true, dRight, fbeRight, odRight, rRight) and
1035+
delta = D::fromFloat(D::toFloat(dLeft) + D::toFloat(dRight)) and
1036+
fromBackEdge = fbeLeft.booleanOr(fbeRight)
1037+
|
1038+
b = bLeft and origdelta = odLeft and reason = rLeft and bRight instanceof SemZeroBound
1039+
or
1040+
b = bRight and origdelta = odRight and reason = rRight and bLeft instanceof SemZeroBound
1041+
)
1042+
or
1043+
exists(
1044+
SemRemExpr rem, SemZeroBound b1, SemZeroBound b2, D::Delta d_max, D::Delta d1, D::Delta d2,
1045+
boolean fbe1, boolean fbe2, D::Delta od1, D::Delta od2, SemReason r1, SemReason r2
1046+
|
1047+
rem = e and
1048+
not (upper = true and semPositive(rem.getRightOperand())) and
1049+
not (upper = true and semPositive(rem.getLeftOperand())) and
1050+
boundedRemExpr(rem, b1, true, d1, fbe1, od1, r1) and
1051+
boundedRemExpr(rem, b2, false, d2, fbe2, od2, r2) and
1052+
(
1053+
if D::toFloat(d1).abs() > D::toFloat(d2).abs()
1054+
then (
1055+
b = b1 and d_max = d1 and fromBackEdge = fbe1 and origdelta = od1 and reason = r1
1056+
) else (
1057+
b = b2 and d_max = d2 and fromBackEdge = fbe2 and origdelta = od2 and reason = r2
1058+
)
1059+
)
1060+
|
1061+
upper = true and delta = D::fromFloat(D::toFloat(d_max).abs() - 1)
1062+
or
1063+
upper = false and delta = D::fromFloat(-D::toFloat(d_max).abs() + 1)
1064+
)
1065+
or
1066+
exists(
1067+
D::Delta dLeft, D::Delta dRight, boolean fbeLeft, boolean fbeRight, D::Delta odLeft,
1068+
D::Delta odRight, SemReason rLeft, SemReason rRight
1069+
|
1070+
boundedMulOperand(e, upper, true, dLeft, fbeLeft, odLeft, rLeft) and
1071+
boundedMulOperand(e, upper, false, dRight, fbeRight, odRight, rRight) and
1072+
delta = D::fromFloat(D::toFloat(dLeft) * D::toFloat(dRight)) and
1073+
fromBackEdge = fbeLeft.booleanOr(fbeRight)
1074+
|
1075+
b instanceof SemZeroBound and origdelta = odLeft and reason = rLeft
1076+
or
1077+
b instanceof SemZeroBound and origdelta = odRight and reason = rRight
1078+
)
10461079
)
10471080
}
10481081

1082+
pragma[nomagic]
10491083
private predicate boundedConditionalExpr(
10501084
SemConditionalExpr cond, SemBound b, boolean upper, boolean branch, D::Delta delta,
10511085
boolean fromBackEdge, D::Delta origdelta, SemReason reason
10521086
) {
10531087
bounded(cond.getBranchExpr(branch), b, delta, upper, fromBackEdge, origdelta, reason)
10541088
}
1089+
1090+
pragma[nomagic]
1091+
private predicate boundedAddOperand(
1092+
SemAddExpr add, boolean upper, SemBound b, boolean isLeft, D::Delta delta, boolean fromBackEdge,
1093+
D::Delta origdelta, SemReason reason
1094+
) {
1095+
// `semValueFlowStep` already handles the case where one of the operands is a constant.
1096+
not semValueFlowStep(add, _, _) and
1097+
(
1098+
isLeft = true and
1099+
bounded(add.getLeftOperand(), b, delta, upper, fromBackEdge, origdelta, reason)
1100+
or
1101+
isLeft = false and
1102+
bounded(add.getRightOperand(), b, delta, upper, fromBackEdge, origdelta, reason)
1103+
)
1104+
}
1105+
1106+
private predicate boundedRemExpr(
1107+
SemRemExpr rem, SemZeroBound b, boolean upper, D::Delta delta, boolean fromBackEdge,
1108+
D::Delta origdelta, SemReason reason
1109+
) {
1110+
bounded(rem.getRightOperand(), b, delta, upper, fromBackEdge, origdelta, reason)
1111+
}
1112+
1113+
/**
1114+
* Define `cmp(true) = <=` and `cmp(false) = >=`.
1115+
*
1116+
* Holds if `mul = left * right`, and in order to know if `mul cmp(upper) 0 + k` (for
1117+
* some `k`) we need to know that `left cmp(upperLeft) 0 + k1` and
1118+
* `right cmp(upperRight) 0 + k2` (for some `k1` and `k2`).
1119+
*/
1120+
pragma[nomagic]
1121+
private predicate boundedMulOperandCand(
1122+
SemMulExpr mul, SemExpr left, SemExpr right, boolean upper, boolean upperLeft,
1123+
boolean upperRight
1124+
) {
1125+
not boundFlowStepMul(mul, _, _) and
1126+
mul.getLeftOperand() = left and
1127+
mul.getRightOperand() = right and
1128+
(
1129+
semPositive(left) and
1130+
(
1131+
// left, right >= 0
1132+
semPositive(right) and
1133+
(
1134+
// max(left * right) = max(left) * max(right)
1135+
upper = true and
1136+
upperLeft = true and
1137+
upperRight = true
1138+
or
1139+
// min(left * right) = min(left) * min(right)
1140+
upper = false and
1141+
upperLeft = false and
1142+
upperRight = false
1143+
)
1144+
or
1145+
// left >= 0, right <= 0
1146+
semNegative(right) and
1147+
(
1148+
// max(left * right) = min(left) * max(right)
1149+
upper = true and
1150+
upperLeft = false and
1151+
upperRight = true
1152+
or
1153+
// min(left * right) = max(left) * min(right)
1154+
upper = false and
1155+
upperLeft = true and
1156+
upperRight = false
1157+
)
1158+
)
1159+
or
1160+
semNegative(left) and
1161+
(
1162+
// left <= 0, right >= 0
1163+
semPositive(right) and
1164+
(
1165+
// max(left * right) = max(left) * min(right)
1166+
upper = true and
1167+
upperLeft = true and
1168+
upperRight = false
1169+
or
1170+
// min(left * right) = min(left) * max(right)
1171+
upper = false and
1172+
upperLeft = false and
1173+
upperRight = true
1174+
)
1175+
or
1176+
// left, right <= 0
1177+
semNegative(right) and
1178+
(
1179+
// max(left * right) = min(left) * min(right)
1180+
upper = true and
1181+
upperLeft = false and
1182+
upperRight = false
1183+
or
1184+
// min(left * right) = max(left) * max(right)
1185+
upper = false and
1186+
upperLeft = true and
1187+
upperRight = true
1188+
)
1189+
)
1190+
)
1191+
}
1192+
1193+
/**
1194+
* Holds if `isLeft = true` and `mul`'s left operand is bounded by `delta`,
1195+
* or if `isLeft = false` and `mul`'s right operand is bounded by `delta`.
1196+
*
1197+
* If `upper = true` the computed bound contributes to an upper bound of `mul`,
1198+
* and if `upper = false` it contributes to a lower bound.
1199+
* The `fromBackEdge`, `origdelta`, `reason` triple are defined by the recursive
1200+
* call to `bounded`.
1201+
*/
1202+
pragma[nomagic]
1203+
private predicate boundedMulOperand(
1204+
SemMulExpr mul, boolean upper, boolean isLeft, D::Delta delta, boolean fromBackEdge,
1205+
D::Delta origdelta, SemReason reason
1206+
) {
1207+
exists(boolean upperLeft, boolean upperRight, SemExpr left, SemExpr right |
1208+
boundedMulOperandCand(mul, left, right, upper, upperLeft, upperRight)
1209+
|
1210+
isLeft = true and
1211+
bounded(left, any(SemZeroBound zb), delta, upperLeft, fromBackEdge, origdelta, reason)
1212+
or
1213+
isLeft = false and
1214+
bounded(right, any(SemZeroBound zb), delta, upperRight, fromBackEdge, origdelta, reason)
1215+
)
1216+
}
10551217
}

cpp/ql/lib/qlpack.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ upgrades: upgrades
88
dependencies:
99
codeql/ssa: ${workspace}
1010
codeql/tutorial: ${workspace}
11+
codeql/util: ${workspace}

cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ private import DataFlowImplCommon
88
private import DataFlowImplSpecific::Private
99
private import DataFlowImplSpecific::Public
1010
private import DataFlowImplCommonPublic
11+
private import codeql.util.Unit
1112
import DataFlow
1213

1314
/**

cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public
1111
private import DataFlowImpl
1212
import DataFlowImplCommonPublic
1313
import FlowStateString
14+
private import codeql.util.Unit
1415

1516
/**
1617
* A configuration of interprocedural data flow analysis. This defines
@@ -328,7 +329,6 @@ private module Config implements FullStateConfigSig {
328329
}
329330

330331
private import Impl<Config> as I
331-
import I
332332

333333
/**
334334
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
@@ -379,6 +379,8 @@ class PathNode instanceof I::PathNode {
379379
final predicate isSinkGroup(string group) { super.isSinkGroup(group) }
380380
}
381381

382+
module PathGraph = I::PathGraph;
383+
382384
private predicate hasFlow(Node source, Node sink, Configuration config) {
383385
exists(PathNode source0, PathNode sink0 |
384386
hasFlowPath(source0, sink0, config) and
@@ -388,7 +390,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) {
388390
}
389391

390392
private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) {
391-
flowPath(source, sink) and source.getConfiguration() = config
393+
I::flowPath(source, sink) and source.getConfiguration() = config
392394
}
393395

394396
private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) }

cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public
1111
private import DataFlowImpl
1212
import DataFlowImplCommonPublic
1313
import FlowStateString
14+
private import codeql.util.Unit
1415

1516
/**
1617
* A configuration of interprocedural data flow analysis. This defines
@@ -328,7 +329,6 @@ private module Config implements FullStateConfigSig {
328329
}
329330

330331
private import Impl<Config> as I
331-
import I
332332

333333
/**
334334
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
@@ -379,6 +379,8 @@ class PathNode instanceof I::PathNode {
379379
final predicate isSinkGroup(string group) { super.isSinkGroup(group) }
380380
}
381381

382+
module PathGraph = I::PathGraph;
383+
382384
private predicate hasFlow(Node source, Node sink, Configuration config) {
383385
exists(PathNode source0, PathNode sink0 |
384386
hasFlowPath(source0, sink0, config) and
@@ -388,7 +390,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) {
388390
}
389391

390392
private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) {
391-
flowPath(source, sink) and source.getConfiguration() = config
393+
I::flowPath(source, sink) and source.getConfiguration() = config
392394
}
393395

394396
private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) }

cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public
1111
private import DataFlowImpl
1212
import DataFlowImplCommonPublic
1313
import FlowStateString
14+
private import codeql.util.Unit
1415

1516
/**
1617
* A configuration of interprocedural data flow analysis. This defines
@@ -328,7 +329,6 @@ private module Config implements FullStateConfigSig {
328329
}
329330

330331
private import Impl<Config> as I
331-
import I
332332

333333
/**
334334
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
@@ -379,6 +379,8 @@ class PathNode instanceof I::PathNode {
379379
final predicate isSinkGroup(string group) { super.isSinkGroup(group) }
380380
}
381381

382+
module PathGraph = I::PathGraph;
383+
382384
private predicate hasFlow(Node source, Node sink, Configuration config) {
383385
exists(PathNode source0, PathNode sink0 |
384386
hasFlowPath(source0, sink0, config) and
@@ -388,7 +390,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) {
388390
}
389391

390392
private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) {
391-
flowPath(source, sink) and source.getConfiguration() = config
393+
I::flowPath(source, sink) and source.getConfiguration() = config
392394
}
393395

394396
private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) }

0 commit comments

Comments
 (0)