Skip to content

Commit 686519e

Browse files
committed
Fix use-after-free in loadable-by-address
1 parent 10f84f0 commit 686519e

File tree

1 file changed

+51
-37
lines changed

1 file changed

+51
-37
lines changed

lib/IRGen/LoadableByAddress.cpp

Lines changed: 51 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,14 +1599,22 @@ class LoadableByAddress : public SILModuleTransform {
15991599

16001600
private:
16011601
void updateLoweredTypes(SILFunction *F);
1602-
void recreateSingleApply(SILInstruction *applyInst);
1603-
bool recreateApply(SILInstruction &I);
1604-
bool recreateConvInstr(SILInstruction &I);
1605-
bool recreateBuiltinInstr(SILInstruction &I);
1606-
bool recreateLoadInstr(SILInstruction &I);
1607-
bool recreateUncheckedEnumDataInstr(SILInstruction &I);
1608-
bool recreateUncheckedTakeEnumDataAddrInst(SILInstruction &I);
1609-
bool fixStoreToBlockStorageInstr(SILInstruction &I);
1602+
void recreateSingleApply(SILInstruction *applyInst,
1603+
SmallVectorImpl<SILInstruction *> &Delete);
1604+
bool recreateApply(SILInstruction &I,
1605+
SmallVectorImpl<SILInstruction *> &Delete);
1606+
bool recreateConvInstr(SILInstruction &I,
1607+
SmallVectorImpl<SILInstruction *> &Delete);
1608+
bool recreateBuiltinInstr(SILInstruction &I,
1609+
SmallVectorImpl<SILInstruction *> &Delete);
1610+
bool recreateLoadInstr(SILInstruction &I,
1611+
SmallVectorImpl<SILInstruction *> &Delete);
1612+
bool recreateUncheckedEnumDataInstr(SILInstruction &I,
1613+
SmallVectorImpl<SILInstruction *> &Delete);
1614+
bool recreateUncheckedTakeEnumDataAddrInst(SILInstruction &I,
1615+
SmallVectorImpl<SILInstruction *> &Delete);
1616+
bool fixStoreToBlockStorageInstr(SILInstruction &I,
1617+
SmallVectorImpl<SILInstruction *> &Delete);
16101618

16111619
private:
16121620
llvm::SetVector<SILFunction *> modFuncs;
@@ -2369,7 +2377,8 @@ getOperandTypeWithCastIfNecessary(SILInstruction *containingInstr, SILValue op,
23692377
return op;
23702378
}
23712379

2372-
void LoadableByAddress::recreateSingleApply(SILInstruction *applyInst) {
2380+
void LoadableByAddress::recreateSingleApply(
2381+
SILInstruction *applyInst, SmallVectorImpl<SILInstruction *> &Delete) {
23732382
auto *F = applyInst->getFunction();
23742383
IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
23752384
// Collect common info
@@ -2380,7 +2389,7 @@ void LoadableByAddress::recreateSingleApply(SILInstruction *applyInst) {
23802389
// else verification will fail with wrong SubstCalleeType
23812390
auto calleInstr = site.getInstruction();
23822391
if (modApplies.remove(calleInstr)) {
2383-
recreateSingleApply(calleInstr);
2392+
recreateSingleApply(calleInstr, Delete);
23842393
callee = applySite.getCallee();
23852394
}
23862395
}
@@ -2490,18 +2499,20 @@ void LoadableByAddress::recreateSingleApply(SILInstruction *applyInst) {
24902499
default:
24912500
llvm_unreachable("Unexpected instr: unknown apply type");
24922501
}
2493-
applyInst->getParent()->erase(applyInst);
2502+
Delete.push_back(applyInst);
24942503
}
24952504

2496-
bool LoadableByAddress::recreateApply(SILInstruction &I) {
2505+
bool LoadableByAddress::recreateApply(
2506+
SILInstruction &I, SmallVectorImpl<SILInstruction *> &Delete) {
24972507
if (!modApplies.count(&I))
24982508
return false;
2499-
recreateSingleApply(&I);
2509+
recreateSingleApply(&I, Delete);
25002510
modApplies.remove(&I);
25012511
return true;
25022512
}
25032513

2504-
bool LoadableByAddress::recreateLoadInstr(SILInstruction &I) {
2514+
bool LoadableByAddress::recreateLoadInstr(
2515+
SILInstruction &I, SmallVectorImpl<SILInstruction *> &Delete) {
25052516
auto *loadInstr = dyn_cast<LoadInst>(&I);
25062517
if (!loadInstr || !loadInstrsOfFunc.count(loadInstr))
25072518
return false;
@@ -2515,11 +2526,12 @@ bool LoadableByAddress::recreateLoadInstr(SILInstruction &I) {
25152526
auto *newInstr = loadBuilder.createLoad(loadInstr->getLoc(), loadOp,
25162527
loadInstr->getOwnershipQualifier());
25172528
loadInstr->replaceAllUsesWith(newInstr);
2518-
loadInstr->getParent()->erase(loadInstr);
2529+
Delete.push_back(loadInstr);
25192530
return true;
25202531
}
25212532

2522-
bool LoadableByAddress::recreateUncheckedEnumDataInstr(SILInstruction &I) {
2533+
bool LoadableByAddress::recreateUncheckedEnumDataInstr(
2534+
SILInstruction &I, SmallVectorImpl<SILInstruction *> &Delete) {
25232535
auto enumInstr = dyn_cast<UncheckedEnumDataInst>(&I);
25242536
if (!enumInstr || !uncheckedEnumDataOfFunc.count(enumInstr))
25252537
return false;
@@ -2547,12 +2559,12 @@ bool LoadableByAddress::recreateUncheckedEnumDataInstr(SILInstruction &I) {
25472559
newType);
25482560
}
25492561
enumInstr->replaceAllUsesWith(newInstr);
2550-
enumInstr->getParent()->erase(enumInstr);
2562+
Delete.push_back(enumInstr);
25512563
return false;
25522564
}
25532565

25542566
bool LoadableByAddress::recreateUncheckedTakeEnumDataAddrInst(
2555-
SILInstruction &I) {
2567+
SILInstruction &I, SmallVectorImpl<SILInstruction *> &Delete) {
25562568
auto *enumInstr = dyn_cast<UncheckedTakeEnumDataAddrInst>(&I);
25572569
if (!enumInstr || !uncheckedTakeEnumDataAddrOfFunc.count(enumInstr))
25582570
return false;
@@ -2577,11 +2589,12 @@ bool LoadableByAddress::recreateUncheckedTakeEnumDataAddrInst(
25772589
newType.getAddressType());
25782590
}
25792591
enumInstr->replaceAllUsesWith(newInstr);
2580-
enumInstr->getParent()->erase(enumInstr);
2592+
Delete.push_back(enumInstr);
25812593
return true;
25822594
}
25832595

2584-
bool LoadableByAddress::fixStoreToBlockStorageInstr(SILInstruction &I) {
2596+
bool LoadableByAddress::fixStoreToBlockStorageInstr(
2597+
SILInstruction &I, SmallVectorImpl<SILInstruction *> &Delete) {
25852598
auto *instr = dyn_cast<StoreInst>(&I);
25862599
if (!instr || !storeToBlockStorageInstrs.count(instr))
25872600
return false;
@@ -2600,7 +2613,8 @@ bool LoadableByAddress::fixStoreToBlockStorageInstr(SILInstruction &I) {
26002613
return true;
26012614
}
26022615

2603-
bool LoadableByAddress::recreateConvInstr(SILInstruction &I) {
2616+
bool LoadableByAddress::recreateConvInstr(SILInstruction &I,
2617+
SmallVectorImpl<SILInstruction *> &Delete) {
26042618
auto *convInstr = dyn_cast<SingleValueInstruction>(&I);
26052619
if (!convInstr || !conversionInstrs.count(convInstr))
26062620
return false;
@@ -2657,11 +2671,12 @@ bool LoadableByAddress::recreateConvInstr(SILInstruction &I) {
26572671
llvm_unreachable("Unexpected conversion instruction");
26582672
}
26592673
convInstr->replaceAllUsesWith(newInstr);
2660-
convInstr->getParent()->erase(convInstr);
2674+
Delete.push_back(convInstr);
26612675
return true;
26622676
}
26632677

2664-
bool LoadableByAddress::recreateBuiltinInstr(SILInstruction &I) {
2678+
bool LoadableByAddress::recreateBuiltinInstr(SILInstruction &I,
2679+
SmallVectorImpl<SILInstruction *> &Delete) {
26652680
auto builtinInstr = dyn_cast<BuiltinInst>(&I);
26662681
if (!builtinInstr || !builtinInstrs.count(builtinInstr))
26672682
return false;
@@ -2682,7 +2697,7 @@ bool LoadableByAddress::recreateBuiltinInstr(SILInstruction &I) {
26822697
builtinInstr->getLoc(), builtinInstr->getName(), newResultTy,
26832698
builtinInstr->getSubstitutions(), newArgs);
26842699
builtinInstr->replaceAllUsesWith(newInstr);
2685-
builtinInstr->getParent()->erase(builtinInstr);
2700+
Delete.push_back(builtinInstr);
26862701
return true;
26872702
}
26882703

@@ -2833,29 +2848,28 @@ void LoadableByAddress::run() {
28332848
// Recreate the instructions in topological order. Some instructions inherit
28342849
// their result type from their operand.
28352850
for (SILFunction &CurrF : *getModule()) {
2851+
SmallVector<SILInstruction *, 32> Delete;
28362852
for (SILBasicBlock &BB : CurrF) {
2837-
SmallVector<SILInstruction *, 32> InstInBlock;
2838-
for (auto &Inst : BB)
2839-
InstInBlock.push_back(&Inst);
2840-
for (SILInstruction *inst : InstInBlock) {
2841-
SILInstruction &I = *inst;
2842-
if (recreateConvInstr(I))
2853+
for (SILInstruction &I : BB) {
2854+
if (recreateConvInstr(I, Delete))
28432855
continue;
2844-
else if (recreateBuiltinInstr(I))
2856+
else if (recreateBuiltinInstr(I, Delete))
28452857
continue;
2846-
else if (recreateUncheckedEnumDataInstr(I))
2858+
else if (recreateUncheckedEnumDataInstr(I, Delete))
28472859
continue;
2848-
else if (recreateUncheckedTakeEnumDataAddrInst(I))
2860+
else if (recreateUncheckedTakeEnumDataAddrInst(I, Delete))
28492861
continue;
2850-
else if (recreateLoadInstr(I))
2862+
else if (recreateLoadInstr(I, Delete))
28512863
continue;
2852-
else if (recreateApply(I))
2864+
else if (recreateApply(I, Delete))
28532865
continue;
28542866
else
2855-
fixStoreToBlockStorageInstr(I);
2867+
fixStoreToBlockStorageInstr(I, Delete);
28562868
}
28572869
}
2858-
}
2870+
for (auto *Inst : Delete)
2871+
Inst->eraseFromParent();
2872+
}
28592873

28602874
// Clean up the data structs:
28612875
modFuncs.clear();

0 commit comments

Comments
 (0)