Skip to content

Commit 0047d81

Browse files
committed
serialization: obfuscate the serialized search paths
We noticed some Swift clients rely on the serialized search paths in the module to find dependencies and droping these paths altogether can lead to build failures like rdar://85840921. This change teaches the serialization to obfuscate the search paths and the deserialization to recover them. This allows clients to keep accessing these paths without exposing them when shipping the module to other users.
1 parent f00f284 commit 0047d81

21 files changed

+139
-27
lines changed

include/swift/AST/FileUnit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,8 @@ class LoadedFile : public FileUnit {
405405
virtual void collectBasicSourceFileInfo(
406406
llvm::function_ref<void(const BasicSourceFileInfo &)> callback) const {}
407407

408+
virtual void collectSerializedSearchPath(
409+
llvm::function_ref<void(StringRef)> callback) const {}
408410
static bool classof(const FileUnit *file) {
409411
return file->getKind() == FileUnitKind::SerializedAST ||
410412
file->getKind() == FileUnitKind::ClangModule ||

include/swift/AST/Module.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,8 @@ class ModuleDecl
833833
void collectBasicSourceFileInfo(
834834
llvm::function_ref<void(const BasicSourceFileInfo &)> callback) const;
835835

836+
void collectSerializedSearchPath(
837+
llvm::function_ref<void(StringRef)> callback) const;
836838
/// Retrieve a fingerprint value that summarizes the contents of this module.
837839
///
838840
/// This interface hash a of a module is guaranteed to change if the interface

include/swift/AST/SearchPathOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ class SearchPathOptions {
103103
/// specified in LLDB from the target.source-map entries.
104104
PathRemapper SearchPathRemapper;
105105

106+
/// Recover the search paths deserialized from .swiftmodule files to their
107+
/// original form.
108+
PathObfuscator DeserializedPathRecoverer;
109+
106110
private:
107111
static StringRef
108112
pathStringFromFrameworkSearchPath(const FrameworkSearchPath &next) {

include/swift/Basic/PathRemapper.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@ class PathRemapper {
5858
}
5959
};
6060

61+
class PathObfuscator {
62+
PathRemapper obfuscator, recoverer;
63+
public:
64+
void addMapping(StringRef FromPrefix, StringRef ToPrefix) {
65+
obfuscator.addMapping(FromPrefix, ToPrefix);
66+
recoverer.addMapping(ToPrefix, FromPrefix);
67+
}
68+
std::string obfuscate(StringRef Path) const {
69+
return obfuscator.remapPath(Path);
70+
}
71+
std::string recover(StringRef Path) const {
72+
return recoverer.remapPath(Path);
73+
}
74+
};
75+
6176
} // end namespace swift
6277

6378
#endif // SWIFT_BASIC_PATHREMAPPER_H

include/swift/Frontend/FrontendOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "swift/Basic/FileTypes.h"
1717
#include "swift/Basic/Version.h"
18+
#include "swift/Basic/PathRemapper.h"
1819
#include "swift/Frontend/FrontendInputsAndOutputs.h"
1920
#include "swift/Frontend/InputFile.h"
2021
#include "llvm/ADT/Hashing.h"
@@ -437,6 +438,10 @@ class FrontendOptions {
437438
/// Whether to include symbols with SPI information in the symbol graph.
438439
bool IncludeSPISymbolsInSymbolGraph = false;
439440

441+
/// This is used to obfuscate the serialized search paths so we don't have
442+
/// to encode the actual paths into the .swiftmodule file.
443+
PathObfuscator serializedPathObfuscator;
444+
440445
private:
441446
static bool canActionEmitDependencies(ActionType);
442447
static bool canActionEmitReferenceDependencies(ActionType);

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ def print_clang_stats : Flag<["-"], "print-clang-stats">,
165165

166166
def serialize_debugging_options : Flag<["-"], "serialize-debugging-options">,
167167
HelpText<"Always serialize options for debugging (default: only for apps)">;
168+
169+
def serialized_path_obfuscate : Separate<["-"], "serialized-path-obfuscate">,
170+
HelpText<"Remap source paths in debug info">, MetaVarName<"<prefix=replacement>">;
171+
168172
def no_serialize_debugging_options :
169173
Flag<["-"], "no-serialize-debugging-options">,
170174
HelpText<"Never serialize options for debugging (default: only for apps)">;

include/swift/Serialization/SerializationOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ namespace swift {
4545
/// Path prefixes that should be rewritten in debug info.
4646
PathRemapper DebuggingOptionsPrefixMap;
4747

48+
/// Obfuscate the serialized paths so we don't have the actual paths encoded
49+
/// in the .swiftmodule file.
50+
PathObfuscator PathObfuscator;
51+
4852
/// Describes a single-file dependency for this module, along with the
4953
/// appropriate strategy for how to verify if it's up-to-date.
5054
class FileDependency {

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,9 @@ class SerializedASTFile final : public LoadedFile {
465465
virtual void collectBasicSourceFileInfo(
466466
llvm::function_ref<void(const BasicSourceFileInfo &)>) const override;
467467

468+
virtual void collectSerializedSearchPath(
469+
llvm::function_ref<void(StringRef)> callback) const override;
470+
468471
static bool classof(const FileUnit *file) {
469472
return file->getKind() == FileUnitKind::SerializedAST;
470473
}

include/swift/Serialization/Validation.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ struct ValidationInfo {
104104
/// \sa validateSerializedAST()
105105
class ExtendedValidationInfo {
106106
SmallVector<StringRef, 4> ExtraClangImporterOpts;
107-
StringRef SDKPath;
107+
std::string SDKPath;
108108
StringRef ModuleABIName;
109109
struct {
110110
unsigned ArePrivateImportsEnabled : 1;
@@ -121,7 +121,7 @@ class ExtendedValidationInfo {
121121
ExtendedValidationInfo() : Bits() {}
122122

123123
StringRef getSDKPath() const { return SDKPath; }
124-
void setSDKPath(StringRef path) {
124+
void setSDKPath(std::string path) {
125125
assert(SDKPath.empty());
126126
SDKPath = path;
127127
}

lib/AST/Module.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,6 +1808,15 @@ void ModuleDecl::collectBasicSourceFileInfo(
18081808
}
18091809
}
18101810

1811+
void ModuleDecl::collectSerializedSearchPath(
1812+
llvm::function_ref<void(StringRef)> callback) const {
1813+
for (const FileUnit *fileUnit : getFiles()) {
1814+
if (auto *serialized = dyn_cast<LoadedFile>(fileUnit)) {
1815+
serialized->collectSerializedSearchPath(callback);
1816+
}
1817+
}
1818+
}
1819+
18111820
Fingerprint ModuleDecl::getFingerprint() const {
18121821
StableHasher hasher = StableHasher::defaultHasher();
18131822
SmallVector<Fingerprint, 16> FPs;

0 commit comments

Comments
 (0)