Skip to content

Commit c38d177

Browse files
committed
[Serialization] Restrict loading swiftmodule files to the builder's SDK
Serialize the canonical name of the SDK used when building a swiftmodule file and use it to ensure that the swiftmodule file is loaded only with the same SDK. The SDK name must be passed down from the frontend. This will report unsupported configurations like: - Installing roots between incompatible SDKs without deleting the swiftmodule files. - Having multiple targets in the same project using different SDKs. - Loading a swiftmodule created with a newer SDK (and stdlib) with an older SDK. All of these lead to hard to investigate deserialization failures and this change should detect them early, before reaching a deserialization failure. rdar://78048939
1 parent 7c653e4 commit c38d177

16 files changed

+85
-3
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,9 @@ ERROR(serialization_name_mismatch_repl,none,
782782
ERROR(serialization_target_incompatible,Fatal,
783783
"module %0 was created for incompatible target %1: %2",
784784
(Identifier, StringRef, StringRef))
785+
ERROR(serialization_sdk_mismatch,Fatal,
786+
"cannot load module %0 built with SDK '%1' when using SDK '%2': %3",
787+
(Identifier, StringRef, StringRef, StringRef))
785788
ERROR(serialization_target_incompatible_repl,none,
786789
"module %0 was created for incompatible target %1: %2",
787790
(Identifier, StringRef, StringRef))

include/swift/AST/SearchPathOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ class SearchPathOptions {
8282
/// would for a non-system header.
8383
bool DisableModulesValidateSystemDependencies = false;
8484

85+
/// Enforce loading only serialized modules built with the same SDK
86+
/// as the context loading it.
87+
bool EnableSameSDKCheck = true;
88+
8589
/// A set of compiled modules that may be ready to use.
8690
std::vector<std::string> CandidateCompiledModules;
8791

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ namespace swift {
127127
/// The target variant SDK version, if known.
128128
Optional<llvm::VersionTuple> VariantSDKVersion;
129129

130+
/// The SDK canonical name, if known.
131+
std::string SDKName;
132+
130133
/// The alternate name to use for the entry point instead of main.
131134
std::string entryPointFunctionName = "main";
132135

include/swift/Option/FrontendOptions.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,9 @@ def target_sdk_version : Separate<["-"], "target-sdk-version">,
823823
def target_variant_sdk_version : Separate<["-"], "target-variant-sdk-version">,
824824
HelpText<"The version of target variant SDK used for compilation">;
825825

826+
def target_sdk_name : Separate<["-"], "target-sdk-name">,
827+
HelpText<"Canonical name of the target SDK used for compilation">;
828+
826829
def extra_clang_options_only : Flag<["-"], "only-use-extra-clang-opts">,
827830
HelpText<"Options passed via -Xcc are sufficient for Clang configuration">;
828831

include/swift/Serialization/SerializationOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ namespace swift {
3535
bool SkipSymbolGraphInheritedDocs = true;
3636
bool IncludeSPISymbolsInSymbolGraph = false;
3737
llvm::VersionTuple UserModuleVersion;
38+
std::string SDKName;
3839

3940
StringRef GroupInfoPath;
4041
StringRef ImportedHeader;

include/swift/Serialization/Validation.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,11 @@ enum class Status {
6666
TargetIncompatible,
6767

6868
/// The module file was built for a target newer than the current target.
69-
TargetTooNew
69+
TargetTooNew,
70+
71+
/// The module file was built with a different SDK than the one in use
72+
/// to build the client.
73+
SDKMismatch
7074
};
7175

7276
/// Returns true if the data looks like it contains a serialized AST.
@@ -80,6 +84,7 @@ struct ValidationInfo {
8084
StringRef miscVersion = {};
8185
version::Version compatibilityVersion = {};
8286
llvm::VersionTuple userModuleVersion;
87+
StringRef sdkName = {};
8388
size_t bytes = 0;
8489
Status status = Status::Malformed;
8590
};

lib/Frontend/CompilerInvocation.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,11 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
774774
}
775775
}
776776

777+
// Get the SDK name.
778+
if (Arg *A = Args.getLastArg(options::OPT_target_sdk_name)) {
779+
Opts.SDKName = A->getValue();
780+
}
781+
777782
if (const Arg *A = Args.getLastArg(OPT_entry_point_function_name)) {
778783
Opts.entryPointFunctionName = A->getValue();
779784
}

lib/Frontend/Frontend.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
150150
serializationOpts.ExtraClangOptions = getClangImporterOptions().ExtraArgs;
151151
serializationOpts.PublicDependentLibraries =
152152
getIRGenOptions().PublicLinkLibraries;
153+
serializationOpts.SDKName = getLangOptions().SDKName;
153154

154155
if (opts.EmitSymbolGraph) {
155156
if (!opts.SymbolGraphOutputDir.empty()) {

lib/Frontend/ModuleInterfaceBuilder.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ bool ModuleInterfaceBuilder::buildSwiftModuleInternal(
257257
if (!getRelativeDepPath(InPath, SDKPath))
258258
SerializationOpts.ModuleInterface = InPath;
259259

260+
SerializationOpts.SDKName = SubInstance.getASTContext().LangOpts.SDKName;
261+
260262
SmallVector<FileDependency, 16> Deps;
261263
bool serializeHashes = FEOpts.SerializeModuleInterfaceDependencyHashes;
262264
if (collectDepsForSerialization(SubInstance, Deps, serializeHashes)) {

lib/Serialization/ModuleFile.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,15 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc,
149149
return error(status);
150150
}
151151

152+
auto clientSDK = ctx.LangOpts.SDKName;
153+
StringRef moduleSDK = Core->SDKName;
154+
if (ctx.SearchPathOpts.EnableSameSDKCheck &&
155+
!moduleSDK.empty() && !clientSDK.empty() &&
156+
moduleSDK != clientSDK) {
157+
status = Status::SDKMismatch;
158+
return error(status);
159+
}
160+
152161
for (const auto &searchPath : Core->SearchPaths)
153162
ctx.addSearchPath(searchPath.Path, searchPath.IsFramework,
154163
searchPath.IsSystem);

0 commit comments

Comments
 (0)