Skip to content

Commit c327f0f

Browse files
committed
Merge branch 'main' into pathinjectionsinks
2 parents 8f141cb + 18c0bce commit c327f0f

File tree

1,567 files changed

+59762
-28517
lines changed

Some content is hidden

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

1,567 files changed

+59762
-28517
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Added models for the `sprintf` variants from the `StrSafe.h` header.

cpp/ql/lib/semmle/code/cpp/ir/dataflow/MustFlow.qll

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ abstract class MustFlowConfiguration extends string {
3131
*/
3232
abstract predicate isSink(Operand sink);
3333

34+
/**
35+
* Holds if data flow through `instr` is prohibited.
36+
*/
37+
predicate isBarrier(Instruction instr) { none() }
38+
3439
/**
3540
* Holds if the additional flow step from `node1` to `node2` must be taken
3641
* into account in the analysis.
@@ -48,18 +53,21 @@ abstract class MustFlowConfiguration extends string {
4853
*/
4954
final predicate hasFlowPath(MustFlowPathNode source, MustFlowPathSink sink) {
5055
this.isSource(source.getInstruction()) and
51-
source.getASuccessor+() = sink
56+
source.getASuccessor*() = sink
5257
}
5358
}
5459

5560
/** Holds if `node` flows from a source. */
5661
pragma[nomagic]
5762
private predicate flowsFromSource(Instruction node, MustFlowConfiguration config) {
58-
config.isSource(node)
59-
or
60-
exists(Instruction mid |
61-
step(mid, node, config) and
62-
flowsFromSource(mid, pragma[only_bind_into](config))
63+
not config.isBarrier(node) and
64+
(
65+
config.isSource(node)
66+
or
67+
exists(Instruction mid |
68+
step(mid, node, config) and
69+
flowsFromSource(mid, pragma[only_bind_into](config))
70+
)
6371
)
6472
}
6573

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -632,20 +632,20 @@ predicate jumpStep(Node n1, Node n2) {
632632
v = globalUse.getVariable() and
633633
n1.(FinalGlobalValue).getGlobalUse() = globalUse
634634
|
635-
globalUse.getIndirectionIndex() = 1 and
635+
globalUse.getIndirection() = 1 and
636636
v = n2.asVariable()
637637
or
638-
v = n2.asIndirectVariable(globalUse.getIndirectionIndex())
638+
v = n2.asIndirectVariable(globalUse.getIndirection())
639639
)
640640
or
641641
exists(Ssa::GlobalDef globalDef |
642642
v = globalDef.getVariable() and
643643
n2.(InitialGlobalValue).getGlobalDef() = globalDef
644644
|
645-
globalDef.getIndirectionIndex() = 1 and
645+
globalDef.getIndirection() = 1 and
646646
v = n1.asVariable()
647647
or
648-
v = n1.asIndirectVariable(globalDef.getIndirectionIndex())
648+
v = n1.asIndirectVariable(globalDef.getIndirection())
649649
)
650650
)
651651
}

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

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -113,22 +113,12 @@ private newtype TDefOrUseImpl =
113113
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
114114
// Represents a final "use" of a global variable to ensure that
115115
// the assignment to a global variable isn't ruled out as dead.
116-
exists(VariableAddressInstruction vai, int defIndex |
117-
vai.getEnclosingIRFunction() = f and
118-
vai.getAstVariable() = v and
119-
isDef(_, _, _, vai, _, defIndex) and
120-
indirectionIndex = [0 .. defIndex] + 1
121-
)
116+
isGlobalUse(v, f, _, indirectionIndex)
122117
} or
123118
TGlobalDefImpl(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
124119
// Represents the initial "definition" of a global variable when entering
125120
// a function body.
126-
exists(VariableAddressInstruction vai |
127-
vai.getEnclosingIRFunction() = f and
128-
vai.getAstVariable() = v and
129-
isUse(_, _, vai, _, indirectionIndex) and
130-
not isDef(_, _, vai.getAUse(), _, _, _)
131-
)
121+
isGlobalDefImpl(v, f, _, indirectionIndex)
132122
} or
133123
TIteratorDef(
134124
Operand iteratorDerefAddress, BaseSourceVariableInstruction container, int indirectionIndex
@@ -150,6 +140,27 @@ private newtype TDefOrUseImpl =
150140
)
151141
}
152142

143+
private predicate isGlobalUse(
144+
GlobalLikeVariable v, IRFunction f, int indirection, int indirectionIndex
145+
) {
146+
exists(VariableAddressInstruction vai |
147+
vai.getEnclosingIRFunction() = f and
148+
vai.getAstVariable() = v and
149+
isDef(_, _, _, vai, indirection, indirectionIndex)
150+
)
151+
}
152+
153+
private predicate isGlobalDefImpl(
154+
GlobalLikeVariable v, IRFunction f, int indirection, int indirectionIndex
155+
) {
156+
exists(VariableAddressInstruction vai |
157+
vai.getEnclosingIRFunction() = f and
158+
vai.getAstVariable() = v and
159+
isUse(_, _, vai, indirection, indirectionIndex) and
160+
not isDef(_, _, _, vai, _, indirectionIndex)
161+
)
162+
}
163+
153164
private predicate unspecifiedTypeIsModifiableAt(Type unspecified, int indirectionIndex) {
154165
indirectionIndex = [1 .. getIndirectionForUnspecifiedType(unspecified).getNumberOfIndirections()] and
155166
exists(CppType cppType |
@@ -438,7 +449,7 @@ class GlobalUse extends UseImpl, TGlobalUse {
438449

439450
override FinalGlobalValue getNode() { result.getGlobalUse() = this }
440451

441-
override int getIndirection() { result = ind + 1 }
452+
override int getIndirection() { isGlobalUse(global, f, result, ind) }
442453

443454
/** Gets the global variable associated with this use. */
444455
GlobalLikeVariable getVariable() { result = global }
@@ -460,7 +471,9 @@ class GlobalUse extends UseImpl, TGlobalUse {
460471
)
461472
}
462473

463-
override SourceVariable getSourceVariable() { sourceVariableIsGlobal(result, global, f, ind) }
474+
override SourceVariable getSourceVariable() {
475+
sourceVariableIsGlobal(result, global, f, this.getIndirection())
476+
}
464477

465478
final override Cpp::Location getLocation() { result = f.getLocation() }
466479

@@ -501,16 +514,18 @@ class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl {
501514

502515
/** Gets the global variable associated with this definition. */
503516
override SourceVariable getSourceVariable() {
504-
sourceVariableIsGlobal(result, global, f, indirectionIndex)
517+
sourceVariableIsGlobal(result, global, f, this.getIndirection())
505518
}
506519

520+
int getIndirection() { result = indirectionIndex }
521+
507522
/**
508523
* Gets the type of this use after specifiers have been deeply stripped
509524
* and typedefs have been resolved.
510525
*/
511526
Type getUnspecifiedType() { result = global.getUnspecifiedType() }
512527

513-
override string toString() { result = "GlobalDef" }
528+
override string toString() { result = "Def of " + this.getSourceVariable() }
514529

515530
override Location getLocation() { result = f.getLocation() }
516531

@@ -980,7 +995,7 @@ class GlobalDef extends TGlobalDef, SsaDefOrUse {
980995
final override Location getLocation() { result = global.getLocation() }
981996

982997
/** Gets a textual representation of this definition. */
983-
override string toString() { result = "GlobalDef" }
998+
override string toString() { result = global.toString() }
984999

9851000
/**
9861001
* Holds if this definition has index `index` in block `block`, and
@@ -990,6 +1005,9 @@ class GlobalDef extends TGlobalDef, SsaDefOrUse {
9901005
global.hasIndexInBlock(block, index, sv)
9911006
}
9921007

1008+
/** Gets the indirection index of this definition. */
1009+
int getIndirection() { result = global.getIndirection() }
1010+
9931011
/** Gets the indirection index of this definition. */
9941012
int getIndirectionIndex() { result = global.getIndirectionIndex() }
9951013

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@ private class FgetsFunction extends DataFlowFunction, TaintFunction, ArrayFuncti
4949
}
5050

5151
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
52-
output.isParameterDeref(0) and
53-
description = "string read by " + this.getName()
54-
or
55-
output.isReturnValue() and
52+
(
53+
output.isParameterDeref(0) or
54+
output.isReturnValue() or
55+
output.isReturnValueDeref()
56+
) and
5657
description = "string read by " + this.getName()
5758
}
5859

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ private class Getaddrinfo extends TaintFunction, ArrayFunction, RemoteFlowSource
157157
override predicate hasArrayWithNullTerminator(int bufParam) { bufParam in [0, 1] }
158158

159159
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
160-
output.isParameterDeref(3) and
160+
output.isParameterDeref(3, 2) and
161161
description = "address returned by " + this.getName()
162162
}
163163
}

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,19 +147,32 @@ private class SnprintfImpl extends Snprintf {
147147

148148
/**
149149
* The Microsoft `StringCchPrintf` function and variants.
150+
* See: https://learn.microsoft.com/en-us/windows/win32/api/strsafe/
151+
* and
152+
* https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms860435(v=msdn.10)
150153
*/
151154
private class StringCchPrintf extends FormattingFunction {
152155
StringCchPrintf() {
153156
this instanceof TopLevelFunction and
154-
this.hasGlobalName([
155-
"StringCchPrintf", "StringCchPrintfEx", "StringCchPrintf_l", "StringCchPrintf_lEx",
156-
"StringCbPrintf", "StringCbPrintfEx", "StringCbPrintf_l", "StringCbPrintf_lEx"
157-
]) and
157+
exists(string baseName |
158+
baseName in [
159+
"StringCchPrintf", //StringCchPrintf(pszDest, cchDest, pszFormat, ...)
160+
"StringCchPrintfEx", //StringCchPrintfEx(pszDest,cchDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, ...)
161+
"StringCchPrintf_l", //StringCchPrintf_l(pszDest, cbDest, pszFormat, locale, ...)
162+
"StringCchPrintf_lEx", //StringCchPrintf_lEx(pszDest, cchDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, locale, ...)
163+
"StringCbPrintf", //StringCbPrintf(pszDest, cbDest, pszFormat, ...)
164+
"StringCbPrintfEx", //StringCbPrintfEx(pszDest, cbDest, ppszDestEnd, pcbRemaining, dwFlags, pszFormat, ...)
165+
"StringCbPrintf_l", //StringCbPrintf_l(pszDest, cbDest, pszFormat, locale, ...)
166+
"StringCbPrintf_lEx" //StringCbPrintf_lEx(pszDest, cbDest, ppszDestEnd, pcbRemaining, dwFlags, pszFormat, locale, ...)
167+
]
168+
|
169+
this.hasGlobalName(baseName + ["", "A", "W"])
170+
) and
158171
not exists(this.getDefinition().getFile().getRelativePath())
159172
}
160173

161174
override int getFormatParameterIndex() {
162-
if this.getName().matches("%Ex") then result = 5 else result = 2
175+
if this.getName().matches("%Ex" + ["", "A", "W"]) then result = 5 else result = 2
163176
}
164177

165178
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = false }

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ private class Send extends AliasFunction, ArrayFunction, SideEffectFunction, Rem
5858
override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 1 and result = 2 }
5959

6060
override predicate hasRemoteFlowSink(FunctionInput input, string description) {
61-
input.isParameterDeref(1) and description = "buffer sent by " + this.getName()
61+
input.isParameterDeref(1, 1) and description = "buffer sent by " + this.getName()
6262
}
6363

6464
override predicate hasSocketInput(FunctionInput input) { input.isParameter(0) }

cpp/ql/lib/semmle/code/cpp/models/interfaces/FunctionInputsAndOutputs.qll

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import semmle.code.cpp.Parameter
88

99
private newtype TFunctionInput =
1010
TInParameter(ParameterIndex i) or
11-
TInParameterDeref(ParameterIndex i) or
11+
TInParameterDeref(ParameterIndex i, int indirectionIndex) { indirectionIndex = [1, 2] } or
1212
TInQualifierObject() or
1313
TInQualifierAddress() or
1414
TInReturnValueDeref()
@@ -245,15 +245,18 @@ class InParameter extends FunctionInput, TInParameter {
245245
*/
246246
class InParameterDeref extends FunctionInput, TInParameterDeref {
247247
ParameterIndex index;
248+
int indirectionIndex;
248249

249-
InParameterDeref() { this = TInParameterDeref(index) }
250+
InParameterDeref() { this = TInParameterDeref(index, indirectionIndex) }
250251

251252
override string toString() { result = "InParameterDeref " + index.toString() }
252253

253254
/** Gets the zero-based index of the parameter. */
254255
ParameterIndex getIndex() { result = index }
255256

256-
override predicate isParameterDeref(ParameterIndex i) { i = index }
257+
override predicate isParameterDeref(ParameterIndex i, int indirection) {
258+
i = index and indirectionIndex = indirection
259+
}
257260
}
258261

259262
/**
@@ -321,10 +324,10 @@ class InReturnValueDeref extends FunctionInput, TInReturnValueDeref {
321324
}
322325

323326
private newtype TFunctionOutput =
324-
TOutParameterDeref(ParameterIndex i) or
327+
TOutParameterDeref(ParameterIndex i, int indirectionIndex) { indirectionIndex = [1, 2] } or
325328
TOutQualifierObject() or
326329
TOutReturnValue() or
327-
TOutReturnValueDeref()
330+
TOutReturnValueDeref(int indirections) { indirections = [1, 2] }
328331

329332
/**
330333
* An output from a function. This can be:
@@ -498,17 +501,16 @@ class FunctionOutput extends TFunctionOutput {
498501
*/
499502
class OutParameterDeref extends FunctionOutput, TOutParameterDeref {
500503
ParameterIndex index;
504+
int indirectionIndex;
501505

502-
OutParameterDeref() { this = TOutParameterDeref(index) }
506+
OutParameterDeref() { this = TOutParameterDeref(index, indirectionIndex) }
503507

504508
override string toString() { result = "OutParameterDeref " + index.toString() }
505509

506510
ParameterIndex getIndex() { result = index }
507511

508-
override predicate isParameterDeref(ParameterIndex i) { i = index }
509-
510512
override predicate isParameterDeref(ParameterIndex i, int ind) {
511-
this.isParameterDeref(i) and ind = 1
513+
i = index and ind = indirectionIndex
512514
}
513515
}
514516

@@ -572,4 +574,8 @@ class OutReturnValueDeref extends FunctionOutput, TOutReturnValueDeref {
572574
override string toString() { result = "OutReturnValueDeref" }
573575

574576
override predicate isReturnValueDeref() { any() }
577+
578+
override predicate isReturnValueDeref(int indirectionIndex) {
579+
this = TOutReturnValueDeref(indirectionIndex)
580+
}
575581
}

cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/RangeAnalysis.qll

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
1717
* `upper` is true, and can be traced back to a guard represented by `reason`.
1818
*/
1919
predicate bounded(Expr e, Bound b, float delta, boolean upper, Reason reason) {
20-
exists(SemanticExprConfig::Expr semExpr |
21-
semExpr.getUnconverted().getUnconvertedResultExpression() = e
22-
|
20+
exists(SemanticExprConfig::Expr semExpr | semExpr.getUnconvertedResultExpression() = e |
2321
semBounded(semExpr, b, delta, upper, reason)
2422
)
2523
}
@@ -30,9 +28,7 @@ predicate bounded(Expr e, Bound b, float delta, boolean upper, Reason reason) {
3028
* The `Expr` may be a conversion.
3129
*/
3230
predicate convertedBounded(Expr e, Bound b, float delta, boolean upper, Reason reason) {
33-
exists(SemanticExprConfig::Expr semExpr |
34-
semExpr.getConverted().getConvertedResultExpression() = e
35-
|
31+
exists(SemanticExprConfig::Expr semExpr | semExpr.getConvertedResultExpression() = e |
3632
semBounded(semExpr, b, delta, upper, reason)
3733
)
3834
}

0 commit comments

Comments
 (0)