diff --git a/chrome/common/safe_browsing/binary_feature_extractor.cc b/chrome/common/safe_browsing/binary_feature_extractor.cc index 7860af73d955e1..8afb0036f4a416 100644 --- a/chrome/common/safe_browsing/binary_feature_extractor.cc +++ b/chrome/common/safe_browsing/binary_feature_extractor.cc @@ -14,6 +14,7 @@ #include "base/files/memory_mapped_file.h" #include "base/metrics/histogram_functions.h" #include "base/strings/string_view_util.h" +#include "build/build_config.h" #include "components/safe_browsing/core/common/proto/csd.pb.h" #include "crypto/hash.h" @@ -28,22 +29,30 @@ bool BinaryFeatureExtractor::ExtractImageFeatures( ExtractHeadersOption options, ClientDownloadRequest_ImageHeaders* image_headers, google::protobuf::RepeatedPtrField* signed_data) { + // Keep the mkstemp FD open and operate on it directly so that no other + // process sharing the temp directory can race a symlink swap between + // creation and use. Immediately unlink the path so it is never re-touched. + base::FilePath temp_dir; + if (!base::GetTempDir(&temp_dir)) { + return false; + } base::FilePath temp_path; - if (!base::CreateTemporaryFile(&temp_path)) { + base::File temp_file = base::CreateAndOpenTemporaryFileInDir( + temp_dir, &temp_path, base::File::FLAG_WIN_TEMPORARY); + if (!temp_file.IsValid()) { return false; } +#if BUILDFLAG(IS_WIN) + temp_file.DeleteOnClose(true); +#else + base::DeleteFile(temp_path); +#endif - if (!base::CopyFile(file_path, temp_path)) { - base::DeleteFile(temp_path); + base::File src_file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); + if (!src_file.IsValid() || !base::CopyFileContents(src_file, temp_file)) { return false; } - base::File temp_file; - temp_file.Initialize(temp_path, base::File::FLAG_OPEN | - base::File::FLAG_READ | - base::File::FLAG_WIN_TEMPORARY | - base::File::FLAG_DELETE_ON_CLOSE); - base::MemoryMappedFile mapped_file; if (!mapped_file.Initialize(std::move(temp_file))) { return false;