Skip to content

Commit c85d99d

Browse files
committed
Merge branch 'main' into re-modeling
2 parents 3023d3b + 18c0bce commit c85d99d

File tree

1,463 files changed

+53836
-30073
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,463 files changed

+53836
-30073
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/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/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/rangeanalysis/new/internal/semantic/SemanticExprSpecific.qll

Lines changed: 13 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -130,17 +130,7 @@ module SemanticExprConfig {
130130

131131
newtype TSsaVariable =
132132
TSsaInstruction(IR::Instruction instr) { instr.hasMemoryResult() } or
133-
TSsaOperand(IR::Operand op) { op.isDefinitionInexact() } or
134-
TSsaPointerArithmeticGuard(ValueNumber instr) {
135-
exists(Guard g, IR::Operand use |
136-
use = instr.getAUse() and use.getIRType() instanceof IR::IRAddressType
137-
|
138-
g.comparesLt(use, _, _, _, _) or
139-
g.comparesLt(_, use, _, _, _) or
140-
g.comparesEq(use, _, _, _, _) or
141-
g.comparesEq(_, use, _, _, _)
142-
)
143-
}
133+
TSsaOperand(IR::PhiInputOperand op) { op.isDefinitionInexact() }
144134

145135
class SsaVariable extends TSsaVariable {
146136
string toString() { none() }
@@ -149,9 +139,7 @@ module SemanticExprConfig {
149139

150140
IR::Instruction asInstruction() { none() }
151141

152-
ValueNumber asPointerArithGuard() { none() }
153-
154-
IR::Operand asOperand() { none() }
142+
IR::PhiInputOperand asOperand() { none() }
155143
}
156144

157145
class SsaInstructionVariable extends SsaVariable, TSsaInstruction {
@@ -166,28 +154,16 @@ module SemanticExprConfig {
166154
final override IR::Instruction asInstruction() { result = instr }
167155
}
168156

169-
class SsaPointerArithmeticGuard extends SsaVariable, TSsaPointerArithmeticGuard {
170-
ValueNumber vn;
171-
172-
SsaPointerArithmeticGuard() { this = TSsaPointerArithmeticGuard(vn) }
173-
174-
final override string toString() { result = vn.toString() }
175-
176-
final override Location getLocation() { result = vn.getLocation() }
177-
178-
final override ValueNumber asPointerArithGuard() { result = vn }
179-
}
180-
181157
class SsaOperand extends SsaVariable, TSsaOperand {
182-
IR::Operand op;
158+
IR::PhiInputOperand op;
183159

184160
SsaOperand() { this = TSsaOperand(op) }
185161

186162
final override string toString() { result = op.toString() }
187163

188164
final override Location getLocation() { result = op.getLocation() }
189165

190-
final override IR::Operand asOperand() { result = op }
166+
final override IR::PhiInputOperand asOperand() { result = op }
191167
}
192168

193169
predicate explicitUpdate(SsaVariable v, Expr sourceExpr) {
@@ -210,97 +186,29 @@ module SemanticExprConfig {
210186
)
211187
}
212188

213-
Expr getAUse(SsaVariable v) {
214-
result.(IR::LoadInstruction).getSourceValue() = v.asInstruction()
215-
or
216-
result = v.asPointerArithGuard().getAnInstruction()
217-
}
189+
Expr getAUse(SsaVariable v) { result.(IR::LoadInstruction).getSourceValue() = v.asInstruction() }
218190

219191
SemType getSsaVariableType(SsaVariable v) {
220192
result = getSemanticType(v.asInstruction().getResultIRType())
193+
or
194+
result = getSemanticType(v.asOperand().getUse().getResultIRType())
221195
}
222196

223197
BasicBlock getSsaVariableBasicBlock(SsaVariable v) {
224198
result = v.asInstruction().getBlock()
225199
or
226-
result = v.asOperand().getUse().getBlock()
227-
}
228-
229-
private newtype TReadPosition =
230-
TReadPositionBlock(IR::IRBlock block) or
231-
TReadPositionPhiInputEdge(IR::IRBlock pred, IR::IRBlock succ) {
232-
exists(IR::PhiInputOperand input |
233-
pred = input.getPredecessorBlock() and
234-
succ = input.getUse().getBlock()
235-
)
236-
}
237-
238-
class SsaReadPosition extends TReadPosition {
239-
string toString() { none() }
240-
241-
Location getLocation() { none() }
242-
243-
predicate hasRead(SsaVariable v) { none() }
244-
}
245-
246-
private class SsaReadPositionBlock extends SsaReadPosition, TReadPositionBlock {
247-
IR::IRBlock block;
248-
249-
SsaReadPositionBlock() { this = TReadPositionBlock(block) }
250-
251-
final override string toString() { result = block.toString() }
252-
253-
final override Location getLocation() { result = block.getLocation() }
254-
255-
final override predicate hasRead(SsaVariable v) {
256-
exists(IR::Operand operand |
257-
operand.getDef() = v.asInstruction() or
258-
operand.getDef() = v.asPointerArithGuard().getAnInstruction()
259-
|
260-
not operand instanceof IR::PhiInputOperand and
261-
operand.getUse().getBlock() = block
262-
)
263-
}
264-
}
265-
266-
private class SsaReadPositionPhiInputEdge extends SsaReadPosition, TReadPositionPhiInputEdge {
267-
IR::IRBlock pred;
268-
IR::IRBlock succ;
269-
270-
SsaReadPositionPhiInputEdge() { this = TReadPositionPhiInputEdge(pred, succ) }
271-
272-
final override string toString() { result = pred.toString() + "->" + succ.toString() }
273-
274-
final override Location getLocation() { result = succ.getLocation() }
275-
276-
final override predicate hasRead(SsaVariable v) {
277-
exists(IR::PhiInputOperand operand |
278-
operand.getDef() = v.asInstruction() or
279-
operand.getDef() = v.asPointerArithGuard().getAnInstruction()
280-
|
281-
operand.getPredecessorBlock() = pred and
282-
operand.getUse().getBlock() = succ
283-
)
284-
}
285-
}
286-
287-
predicate hasReadOfSsaVariable(SsaReadPosition pos, SsaVariable v) { pos.hasRead(v) }
288-
289-
predicate readBlock(SsaReadPosition pos, BasicBlock block) { pos = TReadPositionBlock(block) }
290-
291-
predicate phiInputEdge(SsaReadPosition pos, BasicBlock origBlock, BasicBlock phiBlock) {
292-
pos = TReadPositionPhiInputEdge(origBlock, phiBlock)
200+
result = v.asOperand().getAnyDef().getBlock()
293201
}
294202

295-
predicate phiInput(SsaReadPosition pos, SsaVariable phi, SsaVariable input) {
203+
/** Holds if `inp` is an input to the phi node along the edge originating in `bb`. */
204+
predicate phiInputFromBlock(SsaVariable phi, SsaVariable inp, BasicBlock bb) {
296205
exists(IR::PhiInputOperand operand |
297-
pos = TReadPositionPhiInputEdge(operand.getPredecessorBlock(), operand.getUse().getBlock())
298-
|
206+
bb = operand.getPredecessorBlock() and
299207
phi.asInstruction() = operand.getUse() and
300208
(
301-
input.asInstruction() = operand.getDef()
209+
inp.asInstruction() = operand.getDef()
302210
or
303-
input.asOperand() = operand
211+
inp.asOperand() = operand
304212
)
305213
)
306214
}

0 commit comments

Comments
 (0)