From 635fed042770ff0c253aa2cb4115a2a052077181 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Fri, 9 Jun 2023 00:09:08 +0200 Subject: [PATCH] fs/linux: fix potential copy_file issue sendfile is meant to be run in a loop, since there is no guarantee that a single call copies all the data. The current implementation may lead to corrupt files on linux. --- Utilities/File.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Utilities/File.cpp b/Utilities/File.cpp index 1d982b28cf..48b6e1020e 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -835,9 +835,20 @@ bool fs::copy_file(const std::string& from, const std::string& to, bool overwrit if (::fcopyfile(input, output, 0, COPYFILE_ALL)) #elif defined(__linux__) || defined(__sun) // sendfile will work with non-socket output (i.e. regular file) on Linux 2.6.33+ - off_t bytes_copied = 0; struct ::stat fileinfo = { 0 }; - if (::fstat(input, &fileinfo) == -1 || ::sendfile(output, input, &bytes_copied, fileinfo.st_size) == -1) + bool result = ::fstat(input, &fileinfo) != -1; + if (result) + { + for (off_t bytes_copied = 0; bytes_copied < fileinfo.st_size; /* Do nothing, bytes_copied is increased by sendfile. */) + { + if (::sendfile(output, input, &bytes_copied, fileinfo.st_size - bytes_copied) == -1) + { + result = false; + break; + } + } + } + if (!result) #else #error "Native file copy implementation is missing" #endif