Skip to content

Commit 847c060

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 7d94c24 commit 847c060

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
@@ -3509,9 +3509,9 @@ IRGenModule::getAddrOfLLVMVariable(LinkEntity entity,
35093509
? overrideDeclType
35103510
: entity.getDefaultDeclarationType(*this);
35113511

3512-
auto &entry = GlobalVars[entity];
3513-
if (entry) {
3514-
auto existing = cast<llvm::GlobalValue>(entry);
3512+
auto existingGlobal = GlobalVars[entity];
3513+
if (existingGlobal) {
3514+
auto existing = cast<llvm::GlobalValue>(existingGlobal);
35153515

35163516
// If we're looking to define something, we may need to replace a
35173517
// forward declaration.
@@ -3531,12 +3531,12 @@ IRGenModule::getAddrOfLLVMVariable(LinkEntity entity,
35313531

35323532
// Fall out to the case below, clearing the name so that
35333533
// createVariable doesn't detect a collision.
3534-
entry->setName("");
3534+
existingGlobal->setName("");
35353535

35363536
// Otherwise, we have a previous declaration or definition which
35373537
// we need to ensure has the right type.
35383538
} else {
3539-
return getElementBitCast(entry, defaultType);
3539+
return getElementBitCast(existingGlobal, defaultType);
35403540
}
35413541
}
35423542

@@ -3580,11 +3580,17 @@ IRGenModule::getAddrOfLLVMVariable(LinkEntity entity,
35803580
lazyInitializer->Create(var);
35813581
}
35823582

3583+
if (lazyInitializer) {
3584+
// Protect against self-references that might've been created during
3585+
// the lazy emission.
3586+
existingGlobal = GlobalVars[entity];
3587+
}
3588+
35833589
// If we have an existing entry, destroy it, replacing it with the
3584-
// new variable.
3585-
if (entry) {
3586-
auto existing = cast<llvm::GlobalValue>(entry);
3587-
auto castVar = llvm::ConstantExpr::getBitCast(var, entry->getType());
3590+
// new variable. We only really have to do
3591+
if (existingGlobal) {
3592+
auto existing = cast<llvm::GlobalValue>(existingGlobal);
3593+
auto castVar = llvm::ConstantExpr::getBitCast(var, existing->getType());
35883594
existing->replaceAllUsesWith(castVar);
35893595
existing->eraseFromParent();
35903596
}
@@ -3607,7 +3613,7 @@ IRGenModule::getAddrOfLLVMVariable(LinkEntity entity,
36073613
}
36083614

36093615
// Cache and return.
3610-
entry = var;
3616+
GlobalVars[entity] = var;
36113617
return var;
36123618
}
36133619

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)