Skip to content

Commit a3f25b3

Browse files
committed
Fix a potential use-after-free in lazy global emission.
Extended existential type shapes can trigger this by introducing more entities (and thus causing GlobalVars to be rehashed) during the lazy-emission callback. Fixes rdar://98995607
1 parent dddb4dc commit a3f25b3

File tree

2 files changed

+37
-10
lines changed

2 files changed

+37
-10
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3437,9 +3437,9 @@ IRGenModule::getAddrOfLLVMVariable(LinkEntity entity,
34373437
? overrideDeclType
34383438
: entity.getDefaultDeclarationType(*this);
34393439

3440-
auto &entry = GlobalVars[entity];
3441-
if (entry) {
3442-
auto existing = cast<llvm::GlobalValue>(entry);
3440+
auto existingGlobal = GlobalVars[entity];
3441+
if (existingGlobal) {
3442+
auto existing = cast<llvm::GlobalValue>(existingGlobal);
34433443

34443444
// If we're looking to define something, we may need to replace a
34453445
// forward declaration.
@@ -3459,12 +3459,12 @@ IRGenModule::getAddrOfLLVMVariable(LinkEntity entity,
34593459

34603460
// Fall out to the case below, clearing the name so that
34613461
// createVariable doesn't detect a collision.
3462-
entry->setName("");
3462+
existingGlobal->setName("");
34633463

34643464
// Otherwise, we have a previous declaration or definition which
34653465
// we need to ensure has the right type.
34663466
} else {
3467-
return getElementBitCast(entry, defaultType);
3467+
return getElementBitCast(existingGlobal, defaultType);
34683468
}
34693469
}
34703470

@@ -3508,11 +3508,17 @@ IRGenModule::getAddrOfLLVMVariable(LinkEntity entity,
35083508
lazyInitializer->Create(var);
35093509
}
35103510

3511+
if (lazyInitializer) {
3512+
// Protect against self-references that might've been created during
3513+
// the lazy emission.
3514+
existingGlobal = GlobalVars[entity];
3515+
}
3516+
35113517
// If we have an existing entry, destroy it, replacing it with the
3512-
// new variable.
3513-
if (entry) {
3514-
auto existing = cast<llvm::GlobalValue>(entry);
3515-
auto castVar = llvm::ConstantExpr::getBitCast(var, entry->getType());
3518+
// new variable. We only really have to do
3519+
if (existingGlobal) {
3520+
auto existing = cast<llvm::GlobalValue>(existingGlobal);
3521+
auto castVar = llvm::ConstantExpr::getBitCast(var, existing->getType());
35163522
existing->replaceAllUsesWith(castVar);
35173523
existing->eraseFromParent();
35183524
}
@@ -3535,7 +3541,7 @@ IRGenModule::getAddrOfLLVMVariable(LinkEntity entity,
35353541
}
35363542

35373543
// Cache and return.
3538-
entry = var;
3544+
GlobalVars[entity] = var;
35393545
return var;
35403546
}
35413547

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %target-run-simple-swiftgyb
2+
3+
%for N in range(0, 100):
4+
5+
protocol P${N}<A, B> {
6+
associatedtype A
7+
associatedtype B
8+
}
9+
10+
%end
11+
12+
var array : [Any.Type] = [
13+
%for N in range(0, 100):
14+
(any P${N}<Int, Float>).self,
15+
%end
16+
%for N in range(0, 100):
17+
(any P${N}<Float, String>).self,
18+
%end
19+
]
20+
21+
print(array)

0 commit comments

Comments
 (0)