Skip to content

Commit e4f8e6e

Browse files
authored
Merge pull request #17879 from mikeash/fix-metadata-read-out-of-bounds
[Runtime] In various enumTagSinglePayload functions, don't read getEx traInhabitantIndex or storeExtraInhabitant unless it actually has extra inhabitants.
2 parents 5f42149 + b964cde commit e4f8e6e

File tree

3 files changed

+16
-26
lines changed

3 files changed

+16
-26
lines changed

stdlib/public/runtime/Enum.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,8 @@ unsigned swift::swift_getEnumCaseSinglePayload(const OpaqueValue *value,
146146
auto *payloadWitnesses = payload->getValueWitnesses();
147147
auto size = payloadWitnesses->getSize();
148148
auto numExtraInhabitants = payloadWitnesses->getNumExtraInhabitants();
149-
auto getExtraInhabitantIndex =
150-
(static_cast<const ExtraInhabitantsValueWitnessTable *>(payloadWitnesses)
151-
->getExtraInhabitantIndex);
149+
auto EIVWT = dyn_cast<ExtraInhabitantsValueWitnessTable>(payloadWitnesses);
150+
auto getExtraInhabitantIndex = EIVWT ? EIVWT->getExtraInhabitantIndex : nullptr;
152151

153152
return getEnumTagSinglePayloadImpl(value, emptyCases, payload, size,
154153
numExtraInhabitants,
@@ -163,9 +162,8 @@ void swift::swift_storeEnumTagSinglePayload(OpaqueValue *value,
163162
auto *payloadWitnesses = payload->getValueWitnesses();
164163
auto size = payloadWitnesses->getSize();
165164
auto numExtraInhabitants = payloadWitnesses->getNumExtraInhabitants();
166-
auto storeExtraInhabitant =
167-
(static_cast<const ExtraInhabitantsValueWitnessTable *>(payloadWitnesses)
168-
->storeExtraInhabitant);
165+
auto EIVWT = dyn_cast<ExtraInhabitantsValueWitnessTable>(payloadWitnesses);
166+
auto storeExtraInhabitant = EIVWT ? EIVWT->storeExtraInhabitant : nullptr;
169167

170168
storeEnumTagSinglePayloadImpl(value, whichCase, emptyCases, payload, size,
171169
numExtraInhabitants, storeExtraInhabitant);

stdlib/public/runtime/Metadata.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,9 +1064,8 @@ static unsigned tuple_getEnumTagSinglePayload(const OpaqueValue *enumAddr,
10641064
auto *witnesses = self->getValueWitnesses();
10651065
auto size = witnesses->getSize();
10661066
auto numExtraInhabitants = witnesses->getNumExtraInhabitants();
1067-
auto getExtraInhabitantIndex =
1068-
(static_cast<const ExtraInhabitantsValueWitnessTable *>(witnesses)
1069-
->getExtraInhabitantIndex);
1067+
auto EIVWT = dyn_cast<ExtraInhabitantsValueWitnessTable>(witnesses);
1068+
auto getExtraInhabitantIndex = EIVWT ? EIVWT->getExtraInhabitantIndex : nullptr;
10701069

10711070
return getEnumTagSinglePayloadImpl(enumAddr, numEmptyCases, self, size,
10721071
numExtraInhabitants,
@@ -1080,9 +1079,8 @@ tuple_storeEnumTagSinglePayload(OpaqueValue *enumAddr, unsigned whichCase,
10801079
auto *witnesses = self->getValueWitnesses();
10811080
auto size = witnesses->getSize();
10821081
auto numExtraInhabitants = witnesses->getNumExtraInhabitants();
1083-
auto storeExtraInhabitant =
1084-
(static_cast<const ExtraInhabitantsValueWitnessTable *>(witnesses)
1085-
->storeExtraInhabitant);
1082+
auto EIVWT = dyn_cast<ExtraInhabitantsValueWitnessTable>(witnesses);
1083+
auto storeExtraInhabitant = EIVWT ? EIVWT->storeExtraInhabitant : nullptr;
10861084

10871085
storeEnumTagSinglePayloadImpl(enumAddr, whichCase, numEmptyCases, self, size,
10881086
numExtraInhabitants, storeExtraInhabitant);
@@ -1585,9 +1583,8 @@ static unsigned pod_direct_getEnumTagSinglePayload(const OpaqueValue *enumAddr,
15851583
auto *witnesses = self->getValueWitnesses();
15861584
auto size = witnesses->getSize();
15871585
auto numExtraInhabitants = witnesses->getNumExtraInhabitants();
1588-
auto getExtraInhabitantIndex =
1589-
(static_cast<const ExtraInhabitantsValueWitnessTable *>(witnesses)
1590-
->getExtraInhabitantIndex);
1586+
auto EIVWT = dyn_cast<ExtraInhabitantsValueWitnessTable>(witnesses);
1587+
auto getExtraInhabitantIndex = EIVWT ? EIVWT->getExtraInhabitantIndex : nullptr;
15911588

15921589
return getEnumTagSinglePayloadImpl(enumAddr, numEmptyCases, self, size,
15931590
numExtraInhabitants,
@@ -1601,9 +1598,8 @@ static void pod_direct_storeEnumTagSinglePayload(OpaqueValue *enumAddr,
16011598
auto *witnesses = self->getValueWitnesses();
16021599
auto size = witnesses->getSize();
16031600
auto numExtraInhabitants = witnesses->getNumExtraInhabitants();
1604-
auto storeExtraInhabitant =
1605-
(static_cast<const ExtraInhabitantsValueWitnessTable *>(witnesses)
1606-
->storeExtraInhabitant);
1601+
auto EIVWT = dyn_cast<ExtraInhabitantsValueWitnessTable>(witnesses);
1602+
auto storeExtraInhabitant = EIVWT ? EIVWT->storeExtraInhabitant : nullptr;
16071603

16081604
storeEnumTagSinglePayloadImpl(enumAddr, whichCase, numEmptyCases, self, size,
16091605
numExtraInhabitants, storeExtraInhabitant);

stdlib/public/runtime/MetadataImpl.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -889,10 +889,8 @@ struct NonFixedValueWitnesses :
889889
const Metadata *self) {
890890
auto *payloadWitnesses = self->getValueWitnesses();
891891
auto size = payloadWitnesses->getSize();
892-
auto getExtraInhabitantIndex =
893-
(static_cast<const ExtraInhabitantsValueWitnessTable *>(
894-
payloadWitnesses)
895-
->getExtraInhabitantIndex);
892+
auto EIVWT = dyn_cast<ExtraInhabitantsValueWitnessTable>(payloadWitnesses);
893+
auto getExtraInhabitantIndex = EIVWT ? EIVWT->getExtraInhabitantIndex : nullptr;
896894

897895
return getEnumTagSinglePayloadImpl(enumAddr, numEmptyCases, self, size,
898896
numExtraInhabitants,
@@ -906,10 +904,8 @@ struct NonFixedValueWitnesses :
906904
auto *payloadWitnesses = self->getValueWitnesses();
907905
auto size = payloadWitnesses->getSize();
908906
auto numExtraInhabitants = payloadWitnesses->getNumExtraInhabitants();
909-
auto storeExtraInhabitant =
910-
(static_cast<const ExtraInhabitantsValueWitnessTable *>(
911-
payloadWitnesses)
912-
->storeExtraInhabitant);
907+
auto EIVWT = dyn_cast<ExtraInhabitantsValueWitnessTable>(payloadWitnesses);
908+
auto storeExtraInhabitant = EIVWT ? EIVWT->storeExtraInhabitant : nullptr;
913909

914910
storeEnumTagSinglePayloadImpl(enumAddr, whichCase, numEmptyCases, self,
915911
size, numExtraInhabitants,

0 commit comments

Comments
 (0)