diff --git a/clang/lib/Index/IndexRecordWriter.cpp b/clang/lib/Index/IndexRecordWriter.cpp index 83840c6ccc3d0..e74eecac6425c 100644 --- a/clang/lib/Index/IndexRecordWriter.cpp +++ b/clang/lib/Index/IndexRecordWriter.cpp @@ -17,6 +17,7 @@ #include "llvm/Support/Compression.h" #include "llvm/Support/Errc.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/IOSandbox.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" @@ -258,6 +259,7 @@ IndexRecordWriter::beginRecord(StringRef Filename, uint64_t RecordHash, if (OutRecordFile) *OutRecordFile = RecordName; + auto BypassSandbox = sandbox::scopedDisable(); if (std::error_code EC = fs::access(RecordPath.c_str(), fs::AccessMode::Exist)) { if (EC != errc::no_such_file_or_directory) { @@ -301,6 +303,8 @@ IndexRecordWriter::endRecord(std::string &Error, writeDecls(State.Stream, State.Decls, State.Occurrences, GetSymbolForDecl); } + auto BypassSandbox = sys::sandbox::scopedDisable(); + if (std::error_code EC = sys::fs::create_directory(sys::path::parent_path(State.RecordPath))) { llvm::raw_string_ostream Err(Error); Err << "failed to create directory '" << sys::path::parent_path(State.RecordPath) << "': " << EC.message(); diff --git a/clang/lib/Index/IndexUnitWriter.cpp b/clang/lib/Index/IndexUnitWriter.cpp index c2e41ec6fb9cd..ccc3cdf54d559 100644 --- a/clang/lib/Index/IndexUnitWriter.cpp +++ b/clang/lib/Index/IndexUnitWriter.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/Compression.h" #include "llvm/Support/Errc.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/IOSandbox.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/xxhash.h" @@ -242,6 +243,8 @@ std::optional IndexUnitWriter::isUnitUpToDateForOutputFile( SmallString<256> UnitPath; getUnitPathForOutputFile(FilePath, UnitPath); + auto BypassSandbox = sys::sandbox::scopedDisable(); + llvm::sys::fs::file_status UnitStat; if (std::error_code EC = llvm::sys::fs::status(UnitPath.c_str(), UnitStat)) { if (EC != llvm::errc::no_such_file_or_directory && EC != llvm::errc::delete_pending) { @@ -337,21 +340,11 @@ static void writeVersionInfo(BitstreamWriter &Stream) { bool IndexUnitWriter::write(std::string &Error) { using namespace llvm::sys; + auto BypassSandbox = sandbox::scopedDisable(); + // Determine the working directory. SmallString<128> CWDPath; - if (!FileMgr.getFileSystemOpts().WorkingDir.empty()) { - CWDPath = FileMgr.getFileSystemOpts().WorkingDir; - if (!path::is_absolute(CWDPath)) { - fs::make_absolute(CWDPath); - } - } else { - std::error_code EC = sys::fs::current_path(CWDPath); - if (EC) { - llvm::raw_string_ostream Err(Error); - Err << "failed to determine current working directory: " << EC.message(); - return true; - } - } + FileMgr.makeAbsolutePath(CWDPath); WorkDir = std::string(CWDPath.str()); SmallString<512> Buffer; diff --git a/clang/tools/driver/cc1depscan_main.cpp b/clang/tools/driver/cc1depscan_main.cpp index 168ea191fc9e7..94f46c4bfeb78 100644 --- a/clang/tools/driver/cc1depscan_main.cpp +++ b/clang/tools/driver/cc1depscan_main.cpp @@ -41,6 +41,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/IOSandbox.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Path.h" #include "llvm/Support/PrefixMapper.h" @@ -459,6 +460,7 @@ static void writeResponseFile(raw_ostream &OS, static int scanAndUpdateCC1(const char *Exec, ArrayRef OldArgs, SmallVectorImpl &NewArgs, + llvm::vfs::FileSystem &VFS, DiagnosticsEngine &Diag, const llvm::opt::ArgList &Args, const CASOptions &CASOpts, @@ -469,16 +471,17 @@ static int scanAndUpdateCC1(const char *Exec, ArrayRef OldArgs, }); StringRef WorkingDirectory; - SmallString<128> WorkingDirectoryBuf; + std::string WorkingDirectoryBuf; if (auto *Arg = Args.getLastArg(clang::options::OPT_working_directory)) { WorkingDirectory = Arg->getValue(); } else { - if (llvm::Error E = llvm::errorCodeToError( - llvm::sys::fs::current_path(WorkingDirectoryBuf))) { + auto CWD = VFS.getCurrentWorkingDirectory(); + if (Error E = llvm::errorCodeToError(CWD.getError())) { Diag.Report(diag::err_cas_depscan_failed) << std::move(E); return 1; } + WorkingDirectoryBuf = std::move(*CWD); WorkingDirectory = WorkingDirectoryBuf; } @@ -555,7 +558,10 @@ int cc1depscan_main(ArrayRef Argv, const char *Argv0, std::make_unique(llvm::errs(), *DiagOpts, false); DiagnosticsEngine Diags(new DiagnosticIDs(), *DiagOpts); Diags.setClient(DiagsConsumer.get(), /*ShouldOwnClient=*/false); - auto VFS = llvm::vfs::getRealFileSystem(); + auto VFS = [] { + auto BypassSandbox = llvm::sys::sandbox::scopedDisable(); + return llvm::vfs::getRealFileSystem(); + }(); ProcessWarningOptions(Diags, *DiagOpts, *VFS); if (Diags.hasErrorOccurred()) return 1; @@ -593,8 +599,8 @@ int cc1depscan_main(ArrayRef Argv, const char *Argv0, CompilerInvocation::ParseCASArgs(CASOpts, ParsedCC1Args, Diags); CASOpts.ensurePersistentCAS(); - if (int Ret = scanAndUpdateCC1(Argv0, CC1Args->getValues(), NewArgs, Diags, - Args, CASOpts, RootID)) + if (int Ret = scanAndUpdateCC1(Argv0, CC1Args->getValues(), NewArgs, *VFS, + Diags, Args, CASOpts, RootID)) return Ret; // FIXME: Use OutputBackend to OnDisk only now. @@ -981,8 +987,10 @@ int ScanServer::listen() { // Is this safe to reuse? Or does DependendencyScanningWorkerFileSystem // make some bad assumptions about relative paths? if (!Tool) { - llvm::IntrusiveRefCntPtr UnderlyingFS = - llvm::vfs::createPhysicalFileSystem(); + auto UnderlyingFS = [] { + auto BypassSandbox = llvm::sys::sandbox::scopedDisable(); + return llvm::vfs::createPhysicalFileSystem(); + }(); UnderlyingFS = llvm::cas::createCASProvidingFileSystem( CAS, std::move(UnderlyingFS)); Tool.emplace(Service, std::move(UnderlyingFS)); @@ -1118,8 +1126,10 @@ scanAndUpdateCC1Inline(const char *Exec, ArrayRef InputArgs, dependencies::DependencyScanningService Service( dependencies::ScanningMode::DependencyDirectivesScan, dependencies::ScanningOutputFormat::IncludeTree, CASOpts, DB, Cache); - llvm::IntrusiveRefCntPtr UnderlyingFS = - llvm::vfs::createPhysicalFileSystem(); + auto UnderlyingFS = [] { + auto BypassSandbox = llvm::sys::sandbox::scopedDisable(); + return llvm::vfs::createPhysicalFileSystem(); + }(); UnderlyingFS = llvm::cas::createCASProvidingFileSystem(DB, std::move(UnderlyingFS)); tooling::DependencyScanningTool Tool(Service, std::move(UnderlyingFS)); diff --git a/llvm/lib/CAS/CachingOnDiskFileSystem.cpp b/llvm/lib/CAS/CachingOnDiskFileSystem.cpp index 3b9c6089fcbb3..255918e6a86ec 100644 --- a/llvm/lib/CAS/CachingOnDiskFileSystem.cpp +++ b/llvm/lib/CAS/CachingOnDiskFileSystem.cpp @@ -15,6 +15,8 @@ #include "llvm/CAS/TreePath.h" #include "llvm/Config/config.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/IOSandbox.h" + #include using namespace llvm; @@ -254,6 +256,7 @@ void CachingOnDiskFileSystemImpl::initializeWorkingDirectory() { WorkingDirectory.Entry = &Cache->getRoot(RootPath); WorkingDirectory.Path = WorkingDirectory.Entry->getTreePath().str(); + auto BypassSandbox = sys::sandbox::scopedDisable(); SmallString<128> CWD; if (std::error_code EC = llvm::sys::fs::current_path(CWD)) { (void)EC; @@ -540,6 +543,8 @@ CachingOnDiskFileSystemImpl::getDirectoryIterator(const Twine &Path) { Expected CachingOnDiskFileSystemImpl::preloadRealPath(DirectoryEntry &From, StringRef Remaining) { + auto BypassSandbox = sys::sandbox::scopedDisable(); + PathStorage RemainingStorage(Remaining); SmallString<256> ExpectedRealTreePath; ExpectedRealTreePath = From.getTreePath(); diff --git a/llvm/lib/CAS/OnDiskGraphDB.cpp b/llvm/lib/CAS/OnDiskGraphDB.cpp index 138a2bfa07720..8aed505c9e3b1 100644 --- a/llvm/lib/CAS/OnDiskGraphDB.cpp +++ b/llvm/lib/CAS/OnDiskGraphDB.cpp @@ -58,6 +58,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/IOSandbox.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" @@ -1240,6 +1241,8 @@ OnDiskGraphDB::load(ObjectID ExternalRef) { SmallString<256> Path; getStandalonePath(TrieRecord::getStandaloneFilePrefix(Object.SK), *I, Path); + auto BypassSandbox = sys::sandbox::scopedDisable(); + auto File = sys::fs::openNativeFileForRead(Path); if (!File) return createFileError(Path, File.takeError()); @@ -1343,6 +1346,8 @@ OnDiskContent StandaloneDataInMemory::getContent() const { static Expected createTempFile(StringRef FinalPath, uint64_t Size, OnDiskCASLogger *Logger) { + auto BypassSandbox = sys::sandbox::scopedDisable(); + assert(Size && "Unexpected request for an empty temp file"); Expected File = TempFile::create(FinalPath + ".%%%%%%", Logger); if (!File) @@ -1380,6 +1385,8 @@ Error OnDiskGraphDB::createStandaloneLeaf(IndexProxy &I, ArrayRef Data) { int64_t FileSize = Data.size() + Leaf0; getStandalonePath(TrieRecord::getStandaloneFilePrefix(SK), I, Path); + auto BypassSandbox = sys::sandbox::scopedDisable(); + // Write the file. Don't reuse this mapped_file_region, which is read/write. // Let load() pull up one that's read-only. Expected File = createTempFile(Path, FileSize, Logger.get()); diff --git a/llvm/lib/CAS/UnifiedOnDiskCache.cpp b/llvm/lib/CAS/UnifiedOnDiskCache.cpp index 6ccf0373301d0..c2b9651c2fb20 100644 --- a/llvm/lib/CAS/UnifiedOnDiskCache.cpp +++ b/llvm/lib/CAS/UnifiedOnDiskCache.cpp @@ -83,6 +83,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FileUtilities.h" +#include "llvm/Support/IOSandbox.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/Program.h" @@ -414,6 +415,8 @@ Expected> UnifiedOnDiskCache::open(StringRef RootPath, std::optional SizeLimit, StringRef HashName, unsigned HashByteSize, OnDiskGraphDB::FaultInPolicy FaultInPolicy) { + auto BypassSandbox = sys::sandbox::scopedDisable(); + if (std::error_code EC = sys::fs::create_directories(RootPath)) return createFileError(RootPath, EC); @@ -543,6 +546,8 @@ bool UnifiedOnDiskCache::hasExceededSizeLimit() const { } Error UnifiedOnDiskCache::close(bool CheckSizeLimit) { + auto BypassSandbox = sys::sandbox::scopedDisable(); + if (LockFD == -1) return Error::success(); // already closed. auto CloseLock = make_scope_exit([&]() {