Skip to content

Commit 3adaa21

Browse files
authored
Merge branch 'main' into python/test-container-steps
2 parents 6a5fc3c + c91d1cf commit 3adaa21

File tree

429 files changed

+8792
-8348
lines changed

Some content is hidden

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

429 files changed

+8792
-8348
lines changed

config/identical-files.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll",
4848
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll",
4949
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll",
50-
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplForRegExp.qll",
5150
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll",
5251
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll",
5352
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll",

cpp/ql/lib/qlpack.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ dependencies:
99
codeql/ssa: ${workspace}
1010
codeql/tutorial: ${workspace}
1111
codeql/util: ${workspace}
12+
warnOnImplicitThis: true

cpp/ql/lib/semmle/code/cpp/controlflow/StackVariableReachability.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import cpp
2525
*/
2626
abstract class StackVariableReachability extends string {
2727
bindingset[this]
28-
StackVariableReachability() { length() >= 0 }
28+
StackVariableReachability() { this.length() >= 0 }
2929

3030
/** Holds if `node` is a source for the reachability analysis using variable `v`. */
3131
abstract predicate isSource(ControlFlowNode node, StackVariable v);
@@ -227,7 +227,7 @@ predicate bbSuccessorEntryReachesLoopInvariant(
227227
*/
228228
abstract class StackVariableReachabilityWithReassignment extends StackVariableReachability {
229229
bindingset[this]
230-
StackVariableReachabilityWithReassignment() { length() >= 0 }
230+
StackVariableReachabilityWithReassignment() { this.length() >= 0 }
231231

232232
/** Override this predicate rather than `isSource` (`isSource` is used internally). */
233233
abstract predicate isSourceActual(ControlFlowNode node, StackVariable v);
@@ -330,7 +330,7 @@ abstract class StackVariableReachabilityWithReassignment extends StackVariableRe
330330
*/
331331
abstract class StackVariableReachabilityExt extends string {
332332
bindingset[this]
333-
StackVariableReachabilityExt() { length() >= 0 }
333+
StackVariableReachabilityExt() { this.length() >= 0 }
334334

335335
/** `node` is a source for the reachability analysis using variable `v`. */
336336
abstract predicate isSource(ControlFlowNode node, StackVariable v);

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,14 @@ class SsaPhiNode extends Node, TSsaPhiNode {
562562

563563
/** Gets the source variable underlying this phi node. */
564564
Ssa::SourceVariable getSourceVariable() { result = phi.getSourceVariable() }
565+
566+
/**
567+
* Holds if this phi node is a phi-read node.
568+
*
569+
* Phi-read nodes are like normal phi nodes, but they are inserted based
570+
* on reads instead of writes.
571+
*/
572+
predicate isPhiRead() { phi.isPhiRead() }
565573
}
566574

567575
/**

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,14 @@ class PhiNode extends SsaImpl::DefinitionExt {
10121012
this instanceof SsaImpl::PhiNode or
10131013
this instanceof SsaImpl::PhiReadNode
10141014
}
1015+
1016+
/**
1017+
* Holds if this phi node is a phi-read node.
1018+
*
1019+
* Phi-read nodes are like normal phi nodes, but they are inserted based
1020+
* on reads instead of writes.
1021+
*/
1022+
predicate isPhiRead() { this instanceof SsaImpl::PhiReadNode }
10151023
}
10161024

10171025
class DefinitionExt = SsaImpl::DefinitionExt;

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

Lines changed: 79 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,34 @@ private predicate deconstructSizeExpr(Expr sizeExpr, Expr lengthExpr, int sizeof
206206
}
207207

208208
/** A `Function` that is a call target of an allocation. */
209-
private signature class CallAllocationExprTarget extends Function;
209+
private signature class CallAllocationExprTarget extends Function {
210+
/**
211+
* Gets the index of the input pointer argument to be reallocated, if
212+
* this is a `realloc` function.
213+
*/
214+
int getReallocPtrArg();
215+
216+
/**
217+
* Gets the index of the argument for the allocation size, if any. The actual
218+
* allocation size is the value of this argument multiplied by the result of
219+
* `getSizeMult()`, in bytes.
220+
*/
221+
int getSizeArg();
222+
223+
/**
224+
* Gets the index of an argument that multiplies the allocation size given
225+
* by `getSizeArg`, if any.
226+
*/
227+
int getSizeMult();
228+
229+
/**
230+
* Holds if this allocation requires a
231+
* corresponding deallocation of some sort (most do, but `alloca` for example
232+
* does not). If it is unclear, we default to no (for example a placement `new`
233+
* allocation may or may not require a corresponding `delete`).
234+
*/
235+
predicate requiresDealloc();
236+
}
210237

211238
/**
212239
* This module abstracts over the type of allocation call-targets and provides a
@@ -220,118 +247,68 @@ private signature class CallAllocationExprTarget extends Function;
220247
* function using various heuristics.
221248
*/
222249
private module CallAllocationExprBase<CallAllocationExprTarget Target> {
223-
/** A module that contains the collection of member-predicates required on `Target`. */
224-
signature module Param {
225-
/**
226-
* Gets the index of the input pointer argument to be reallocated, if
227-
* this is a `realloc` function.
228-
*/
229-
int getReallocPtrArg(Target target);
230-
231-
/**
232-
* Gets the index of the argument for the allocation size, if any. The actual
233-
* allocation size is the value of this argument multiplied by the result of
234-
* `getSizeMult()`, in bytes.
235-
*/
236-
int getSizeArg(Target target);
237-
238-
/**
239-
* Gets the index of an argument that multiplies the allocation size given
240-
* by `getSizeArg`, if any.
241-
*/
242-
int getSizeMult(Target target);
243-
244-
/**
245-
* Holds if this allocation requires a
246-
* corresponding deallocation of some sort (most do, but `alloca` for example
247-
* does not). If it is unclear, we default to no (for example a placement `new`
248-
* allocation may or may not require a corresponding `delete`).
249-
*/
250-
predicate requiresDealloc(Target target);
251-
}
252-
253250
/**
254-
* A module that abstracts over a collection of predicates in
255-
* the `Param` module). This should really be member-predicates
256-
* on `CallAllocationExprTarget`, but we cannot yet write this in QL.
251+
* An allocation expression that is a function call, such as call to `malloc`.
257252
*/
258-
module With<Param P> {
259-
private import P
260-
261-
/**
262-
* An allocation expression that is a function call, such as call to `malloc`.
263-
*/
264-
class CallAllocationExprImpl instanceof FunctionCall {
265-
Target target;
266-
267-
CallAllocationExprImpl() {
268-
target = this.getTarget() and
269-
// realloc(ptr, 0) only frees the pointer
270-
not (
271-
exists(getReallocPtrArg(target)) and
272-
this.getArgument(getSizeArg(target)).getValue().toInt() = 0
273-
) and
274-
// these are modeled directly (and more accurately), avoid duplication
275-
not exists(NewOrNewArrayExpr new | new.getAllocatorCall() = this)
276-
}
277-
278-
string toString() { result = super.toString() }
279-
280-
Expr getSizeExprImpl() {
281-
exists(Expr sizeExpr | sizeExpr = super.getArgument(getSizeArg(target)) |
282-
if exists(getSizeMult(target))
283-
then result = sizeExpr
284-
else
285-
exists(Expr lengthExpr |
286-
deconstructSizeExpr(sizeExpr, lengthExpr, _) and
287-
result = lengthExpr
288-
)
289-
)
290-
}
291-
292-
int getSizeMultImpl() {
293-
// malloc with multiplier argument that is a constant
294-
result = super.getArgument(getSizeMult(target)).getValue().toInt()
295-
or
296-
// malloc with no multiplier argument
297-
not exists(getSizeMult(target)) and
298-
deconstructSizeExpr(super.getArgument(getSizeArg(target)), _, result)
299-
}
300-
301-
int getSizeBytesImpl() {
302-
result = this.getSizeExprImpl().getValue().toInt() * this.getSizeMultImpl()
303-
}
304-
305-
Expr getReallocPtrImpl() { result = super.getArgument(getReallocPtrArg(target)) }
306-
307-
Type getAllocatedElementTypeImpl() {
308-
result =
309-
super.getFullyConverted().getType().stripTopLevelSpecifiers().(PointerType).getBaseType() and
310-
not result instanceof VoidType
311-
}
312-
313-
predicate requiresDeallocImpl() { requiresDealloc(target) }
253+
class CallAllocationExprImpl instanceof FunctionCall {
254+
Target target;
255+
256+
CallAllocationExprImpl() {
257+
target = this.getTarget() and
258+
// realloc(ptr, 0) only frees the pointer
259+
not (
260+
exists(target.getReallocPtrArg()) and
261+
this.getArgument(target.getSizeArg()).getValue().toInt() = 0
262+
) and
263+
// these are modeled directly (and more accurately), avoid duplication
264+
not exists(NewOrNewArrayExpr new | new.getAllocatorCall() = this)
314265
}
315-
}
316-
}
317266

318-
private module CallAllocationExpr {
319-
private module Param implements CallAllocationExprBase<AllocationFunction>::Param {
320-
int getReallocPtrArg(AllocationFunction f) { result = f.getReallocPtrArg() }
267+
string toString() { result = super.toString() }
268+
269+
Expr getSizeExprImpl() {
270+
exists(Expr sizeExpr | sizeExpr = super.getArgument(target.getSizeArg()) |
271+
if exists(target.getSizeMult())
272+
then result = sizeExpr
273+
else
274+
exists(Expr lengthExpr |
275+
deconstructSizeExpr(sizeExpr, lengthExpr, _) and
276+
result = lengthExpr
277+
)
278+
)
279+
}
280+
281+
int getSizeMultImpl() {
282+
// malloc with multiplier argument that is a constant
283+
result = super.getArgument(target.getSizeMult()).getValue().toInt()
284+
or
285+
// malloc with no multiplier argument
286+
not exists(target.getSizeMult()) and
287+
deconstructSizeExpr(super.getArgument(target.getSizeArg()), _, result)
288+
}
289+
290+
int getSizeBytesImpl() {
291+
result = this.getSizeExprImpl().getValue().toInt() * this.getSizeMultImpl()
292+
}
321293

322-
int getSizeArg(AllocationFunction f) { result = f.getSizeArg() }
294+
Expr getReallocPtrImpl() { result = super.getArgument(target.getReallocPtrArg()) }
323295

324-
int getSizeMult(AllocationFunction f) { result = f.getSizeMult() }
296+
Type getAllocatedElementTypeImpl() {
297+
result =
298+
super.getFullyConverted().getType().stripTopLevelSpecifiers().(PointerType).getBaseType() and
299+
not result instanceof VoidType
300+
}
325301

326-
predicate requiresDealloc(AllocationFunction f) { f.requiresDealloc() }
302+
predicate requiresDeallocImpl() { target.requiresDealloc() }
327303
}
304+
}
328305

306+
private module CallAllocationExpr {
329307
/**
330308
* A class that provides the implementation of `AllocationExpr` for an allocation
331309
* that calls an `AllocationFunction`.
332310
*/
333-
private class Base =
334-
CallAllocationExprBase<AllocationFunction>::With<Param>::CallAllocationExprImpl;
311+
private class Base = CallAllocationExprBase<AllocationFunction>::CallAllocationExprImpl;
335312

336313
class CallAllocationExpr extends AllocationExpr, Base {
337314
override Expr getSizeExpr() { result = super.getSizeExprImpl() }
@@ -437,7 +414,7 @@ private module HeuristicAllocation {
437414
int sizeArg;
438415

439416
HeuristicAllocationFunctionByName() {
440-
Function.super.getName().matches("%alloc%") and
417+
Function.super.getName().matches(["%alloc%", "%Alloc%"]) and
441418
Function.super.getUnspecifiedType() instanceof PointerType and
442419
sizeArg = unique( | | getAnUnsignedParameter(this))
443420
}
@@ -452,22 +429,11 @@ private module HeuristicAllocation {
452429
override predicate requiresDealloc() { none() }
453430
}
454431

455-
private module Param implements CallAllocationExprBase<HeuristicAllocationFunction>::Param {
456-
int getReallocPtrArg(HeuristicAllocationFunction f) { result = f.getReallocPtrArg() }
457-
458-
int getSizeArg(HeuristicAllocationFunction f) { result = f.getSizeArg() }
459-
460-
int getSizeMult(HeuristicAllocationFunction f) { result = f.getSizeMult() }
461-
462-
predicate requiresDealloc(HeuristicAllocationFunction f) { f.requiresDealloc() }
463-
}
464-
465432
/**
466433
* A class that provides the implementation of `AllocationExpr` for an allocation
467434
* that calls an `HeuristicAllocationFunction`.
468435
*/
469-
private class Base =
470-
CallAllocationExprBase<HeuristicAllocationFunction>::With<Param>::CallAllocationExprImpl;
436+
private class Base = CallAllocationExprBase<HeuristicAllocationFunction>::CallAllocationExprImpl;
471437

472438
private class CallAllocationExpr extends HeuristicAllocationExpr, Base {
473439
override Expr getSizeExpr() { result = super.getSizeExprImpl() }

cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisStage.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ module RangeStage<
277277
*/
278278
private class SafeCastExpr extends ConvertOrBoxExpr {
279279
SafeCastExpr() {
280-
conversionCannotOverflow(getTrackedType(pragma[only_bind_into](getOperand())),
280+
conversionCannotOverflow(getTrackedType(pragma[only_bind_into](this.getOperand())),
281281
pragma[only_bind_out](getTrackedType(this)))
282282
}
283283
}

cpp/ql/lib/upgrades/282c13bfdbcbd57a887972b47a471342a4ad5507/member_function_this_type.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class ClassPointerType extends @derivedtype {
2424

2525
Class getBaseType() { derivedtypes(this, _, _, result) }
2626

27-
string toString() { result = getBaseType().toString() + "*" }
27+
string toString() { result = this.getBaseType().toString() + "*" }
2828
}
2929

3030
class DefinedMemberFunction extends @function {

cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ VariableAccess getAVariableAccess(Expr e) { e.getAChild*() = result }
4747
* Holds if `(n, state)` pair represents the source of flow for the size
4848
* expression associated with `alloc`.
4949
*/
50-
predicate hasSize(AllocationExpr alloc, DataFlow::Node n, int state) {
50+
predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) {
5151
exists(VariableAccess va, Expr size, int delta |
5252
size = alloc.getSizeExpr() and
5353
// Get the unique variable in a size expression like `x` in `malloc(x + 1)`.

cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,10 @@ module InvalidPointerToDerefConfig implements DataFlow::ConfigSig {
229229

230230
pragma[inline]
231231
predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink(sink, _, _) }
232+
233+
predicate isBarrier(DataFlow::Node node) {
234+
node = any(DataFlow::SsaPhiNode phi | not phi.isPhiRead()).getAnInput(true)
235+
}
232236
}
233237

234238
module InvalidPointerToDerefFlow = DataFlow::Global<InvalidPointerToDerefConfig>;

0 commit comments

Comments
 (0)