Skip to content

Commit 6f7f68f

Browse files
committed
Merge branch 'main' into rdmarsh2/cpp/ir-synthetic-destructors
2 parents 942a4ed + 63a5b49 commit 6f7f68f

File tree

119 files changed

+1676
-588
lines changed

Some content is hidden

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

119 files changed

+1676
-588
lines changed

.bazelrc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
common --enable_platform_specific_config
2+
common --enable_bzlmod
3+
# because we use --override_module with `%workspace%`, the lock file is not stable
4+
common --lockfile_mode=off
5+
6+
# when building from this repository in isolation, the internal repository will not be found at ..
7+
# where `MODULE.bazel` looks for it. The following will get us past the module loading phase, so
8+
# that we can build things that do not rely on that
9+
common --override_module=semmle_code=%workspace%/misc/bazel/semmle_code_stub
210

311
build --repo_env=CC=clang --repo_env=CXX=clang++
412

.bazelversion

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6.3.1
1+
6.5.0

CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
# Bazel (excluding BUILD.bazel files)
2727
WORKSPACE.bazel @github/codeql-ci-reviewers
28+
MODULE.bazel @github/codeql-ci-reviewers
2829
.bazelversion @github/codeql-ci-reviewers
2930
.bazelrc @github/codeql-ci-reviewers
3031
**/*.bzl @github/codeql-ci-reviewers

MODULE.bazel

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
module(
2+
name = "codeql",
3+
version = "0.0",
4+
)
5+
6+
# this points to our internal repository when `codeql` is checked out as a submodule thereof
7+
# when building things from `codeql` independently this is stubbed out in `.bazelrc`
8+
bazel_dep(name = "semmle_code", version = "0.0")
9+
local_path_override(
10+
module_name = "semmle_code",
11+
path = "..",
12+
)
13+
14+
# see https://registry.bazel.build/ for a list of available packages
15+
16+
bazel_dep(name = "platforms", version = "0.0.8")
17+
bazel_dep(name = "rules_pkg", version = "0.9.1")
18+
bazel_dep(name = "rules_nodejs", version = "6.0.3")
19+
bazel_dep(name = "rules_python", version = "0.31.0")
20+
bazel_dep(name = "bazel_skylib", version = "1.5.0")
21+
bazel_dep(name = "abseil-cpp", version = "20240116.0", repo_name = "absl")
22+
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
23+
bazel_dep(name = "fmt", version = "10.0.0")
24+
25+
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
26+
pip.parse(
27+
hub_name = "codegen_deps",
28+
python_version = "3.11",
29+
requirements_lock = "//misc/codegen:requirements_lock.txt",
30+
)
31+
use_repo(pip, "codegen_deps")
32+
33+
swift_deps = use_extension("//swift/third_party:load.bzl", "swift_deps")
34+
use_repo(
35+
swift_deps,
36+
"binlog",
37+
"picosha2",
38+
"swift_prebuilt_darwin_x86_64",
39+
"swift_prebuilt_linux",
40+
"swift_toolchain_linux",
41+
"swift_toolchain_macos",
42+
)
43+
44+
node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node")
45+
node.toolchain(
46+
name = "nodejs",
47+
node_version = "18.15.0",
48+
)
49+
use_repo(node, "nodejs", "nodejs_toolchains")
50+
51+
register_toolchains(
52+
"@nodejs_toolchains//:all",
53+
)

WORKSPACE.bazel

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,2 @@
1-
# Please notice that any bazel targets and definitions in this repository are currently experimental
2-
# and for internal use only.
3-
4-
workspace(name = "codeql")
5-
6-
load("//misc/bazel:workspace.bzl", "codeql_workspace")
7-
8-
codeql_workspace()
9-
10-
load("//misc/bazel:workspace_deps.bzl", "codeql_workspace_deps")
11-
12-
codeql_workspace_deps()
1+
# please use MODULE.bazel to add dependencies
2+
# this empty file is required by internal repositories, don't remove it

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

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,29 +55,12 @@ private newtype TIRDataFlowNode =
5555
TFinalParameterNode(Parameter p, int indirectionIndex) {
5656
exists(Ssa::FinalParameterUse use |
5757
use.getParameter() = p and
58-
use.getIndirectionIndex() = indirectionIndex and
59-
parameterIsRedefined(p)
58+
use.getIndirectionIndex() = indirectionIndex
6059
)
6160
} or
6261
TFinalGlobalValue(Ssa::GlobalUse globalUse) or
6362
TInitialGlobalValue(Ssa::GlobalDef globalUse)
6463

65-
/**
66-
* Holds if the value of `*p` (or `**p`, `***p`, etc.) is redefined somewhere in the body
67-
* of the enclosing function of `p`.
68-
*
69-
* Only parameters satisfying this predicate will generate a `FinalParameterNode` transferring
70-
* flow out of the function.
71-
*/
72-
private predicate parameterIsRedefined(Parameter p) {
73-
exists(Ssa::Def def |
74-
def.getSourceVariable().getBaseVariable().(Ssa::BaseIRVariable).getIRVariable().getAst() = p and
75-
def.getIndirectionIndex() = 0 and
76-
def.getIndirection() > 1 and
77-
not def.getValue().asInstruction() instanceof InitializeParameterInstruction
78-
)
79-
}
80-
8164
/**
8265
* An operand that is defined by a `FieldAddressInstruction`.
8366
*/

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

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ private import DataFlowUtil
44
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
7+
private import semmle.code.cpp.models.interfaces.Taint as Taint
8+
private import semmle.code.cpp.models.interfaces.PartialFlow as PartialFlow
9+
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs as FIO
710
private import semmle.code.cpp.ir.internal.IRCppLanguage
11+
private import semmle.code.cpp.ir.dataflow.internal.ModelUtil
812
private import DataFlowPrivate
913
private import ssa0.SsaInternals as SsaInternals0
1014
import SsaInternalsCommon
@@ -138,12 +142,11 @@ private newtype TDefOrUseImpl =
138142
isIteratorUse(container, iteratorAddress, _, indirectionIndex)
139143
} or
140144
TFinalParameterUse(Parameter p, int indirectionIndex) {
141-
// Avoid creating parameter nodes if there is no definitions of the variable other than the initializaion.
142-
exists(SsaInternals0::Def def |
143-
def.getSourceVariable().getBaseVariable().(BaseIRVariable).getIRVariable().getAst() = p and
144-
not def.getValue().asInstruction() instanceof InitializeParameterInstruction and
145-
underlyingTypeIsModifiableAt(p.getUnderlyingType(), indirectionIndex)
146-
)
145+
underlyingTypeIsModifiableAt(p.getUnderlyingType(), indirectionIndex) and
146+
// Only create an SSA read for the final use of a parameter if there's
147+
// actually a body of the enclosing function. If there's no function body
148+
// then we'll never need to flow out of the function anyway.
149+
p.getFunction().hasDefinition()
147150
}
148151

149152
private predicate isGlobalUse(
@@ -796,10 +799,58 @@ private Node getAPriorDefinition(SsaDefOrUse defOrUse) {
796799
)
797800
}
798801

802+
private predicate inOut(FIO::FunctionInput input, FIO::FunctionOutput output) {
803+
exists(int indirectionIndex |
804+
input.isQualifierObject(indirectionIndex) and
805+
output.isQualifierObject(indirectionIndex)
806+
or
807+
exists(int i |
808+
input.isParameterDeref(i, indirectionIndex) and
809+
output.isParameterDeref(i, indirectionIndex)
810+
)
811+
)
812+
}
813+
814+
/**
815+
* Holds if there should not be use-use flow out of `n`. That is, `n` is
816+
* an out-barrier to use-use flow. This includes:
817+
*
818+
* - an input to a call that would be assumed to have use-use flow to the same
819+
* argument as an output, but this flow should be blocked because the
820+
* function is modeled with another flow to that output (for example the
821+
* first argument of `strcpy`).
822+
* - a conversion that flows to such an input.
823+
*/
824+
private predicate modeledFlowBarrier(Node n) {
825+
exists(
826+
FIO::FunctionInput input, FIO::FunctionOutput output, CallInstruction call,
827+
PartialFlow::PartialFlowFunction partialFlowFunc
828+
|
829+
n = callInput(call, input) and
830+
inOut(input, output) and
831+
exists(callOutput(call, output)) and
832+
partialFlowFunc = call.getStaticCallTarget() and
833+
not partialFlowFunc.isPartialWrite(output)
834+
|
835+
call.getStaticCallTarget().(DataFlow::DataFlowFunction).hasDataFlow(_, output)
836+
or
837+
call.getStaticCallTarget().(Taint::TaintFunction).hasTaintFlow(_, output)
838+
)
839+
or
840+
exists(Operand operand, Instruction instr, Node n0, int indirectionIndex |
841+
modeledFlowBarrier(n0) and
842+
nodeHasInstruction(n0, instr, indirectionIndex) and
843+
conversionFlow(operand, instr, false, _) and
844+
nodeHasOperand(n, operand, indirectionIndex)
845+
)
846+
}
847+
799848
/** Holds if there is def-use or use-use flow from `nodeFrom` to `nodeTo`. */
800849
predicate ssaFlow(Node nodeFrom, Node nodeTo) {
801850
exists(Node nFrom, boolean uncertain, SsaDefOrUse defOrUse |
802-
ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and nodeFrom != nodeTo
851+
ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and
852+
not modeledFlowBarrier(nFrom) and
853+
nodeFrom != nodeTo
803854
|
804855
if uncertain = true then nodeFrom = [nFrom, getAPriorDefinition(defOrUse)] else nodeFrom = nFrom
805856
)

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 }

0 commit comments

Comments
 (0)