From cc126a02b13b4791ccd85a4a574974d107bed67f Mon Sep 17 00:00:00 2001 From: Stefano Bonicatti Date: Wed, 1 Nov 2023 15:05:27 +0100 Subject: [PATCH] temp --- osquery/filesystem/filesystem.cpp | 82 +++++++++++++++++++++++++------ osquery/filesystem/filesystem.h | 17 ++++--- osquery/utils/status/status.h | 2 +- 3 files changed, 78 insertions(+), 23 deletions(-) diff --git a/osquery/filesystem/filesystem.cpp b/osquery/filesystem/filesystem.cpp index 69b9311800ed..44401ba20f3a 100644 --- a/osquery/filesystem/filesystem.cpp +++ b/osquery/filesystem/filesystem.cpp @@ -33,9 +33,9 @@ #if WIN32 #include #endif -#include - +#include #include +#include namespace fs = boost::filesystem; namespace errc = boost::system::errc; @@ -158,14 +158,22 @@ Status readWithSize(OpenReadableFile& file_handle, // } } while (total_bytes < size); + + /* NOTE: If the read happens successfully but in the end we get less than what we asked, + we cannot assume that this is an error necessarily, since the file could be one with no size, + so knowing how much data to read before hand is impossible. */ + content.resize(total_bytes); + + + return Status::success(); } -Expected readFile(const fs::path& path, bool log) { +ReadResult readFile(const fs::path& path, bool log) { OpenReadableFile handle(path, false); if (handle.fd == nullptr || !handle.fd->isValid()) { - return Status::failure("Cannot open file for reading: " + - handle.fd->getFilePath().string()); + return ReadResult::failure("Cannot open file for reading: " + + handle.fd->getFilePath().string()); } std::uint64_t file_size = handle.fd->size(); @@ -173,24 +181,66 @@ Expected readFile(const fs::path& path, bool log) { // Apply the max byte-read. auto read_max = FLAGS_read_max; if (file_size > read_max) { - auto s = - Status::failure("Cannot read " + path.string() + - " size exceeds limit: " + std::to_string(file_size) + - " > " + std::to_string(read_max)); + auto error_message = "Cannot read " + path.string() + + " size exceeds limit: " + std::to_string(file_size) + + " > " + std::to_string(read_max); if (log) { - LOG(WARNING) << s.getMessage(); + LOG(WARNING) << error_message; } - return s; + return ReadResult::failure(error_message); } - readWithSize() + std::string content; - return Status::success(); + + + auto status = readWithSize(handle, content, file_size); + + if (!status.ok()) { + return ReadResult::failure(status.getMessage()); + } + + return content; } -Status readFile(const fs::path& path, std::string& content, bool log) { - return readFile( - path, ([&content](std::string_view buffer) { content += buffer; }), log); +ReadResult readFile(const fs::path& path, + std::size_t block_size, + std::function callback, + bool log) { + OpenReadableFile handle(path, false); + if (handle.fd == nullptr || !handle.fd->isValid()) { + return ReadResult::failure("Cannot open file for reading: " + + handle.fd->getFilePath().string()); + } + + std::uint64_t file_size = handle.fd->size(); + + // Apply the max byte-read. + auto read_max = FLAGS_read_max; + if (file_size > read_max) { + auto error_message = "Cannot read " + path.string() + + " size exceeds limit: " + std::to_string(file_size) + + " > " + std::to_string(read_max); + if (log) { + LOG(WARNING) << error_message; + } + return ReadResult::failure(error_message); + } + + std::string content; + std::size_t total_bytes = 0; + + do { + auto status = readWithSize(handle, content, file_size); + + if (!status.ok()) { + return ReadResult::failure(status.getMessage()); + } + + total_bytes += content.size(); + + + } while () } Status isWritable(const fs::path& path, bool effective) { diff --git a/osquery/filesystem/filesystem.h b/osquery/filesystem/filesystem.h index e7682525d256..dce5bd2c8a8c 100644 --- a/osquery/filesystem/filesystem.h +++ b/osquery/filesystem/filesystem.h @@ -31,6 +31,10 @@ enum GlobLimits : size_t { GLOB_NO_CANON = 0x4, }; +enum class ReadError { + GenericError, +}; + inline GlobLimits operator|(GlobLimits a, GlobLimits b) { return static_cast(static_cast(a) | static_cast(b)); @@ -45,6 +49,7 @@ const std::string kSQLGlobRecursive{kSQLGlobWildcard + kSQLGlobWildcard}; /// Calls the setlocale() API, only used on Windows void initializeFilesystemAPILocale(); +using ReadResult = Expected; /** * @brief Read a file from disk. * @@ -59,14 +64,14 @@ void initializeFilesystemAPILocale(); * * @return an instance of Status, indicating success or failure. */ -Status readFile(const boost::filesystem::path& path, - std::string& content, - bool log = true); +ReadResult readFile(const boost::filesystem::path& path, + std::string& content, + bool log = true); /// Internal representation for predicate-based chunk reading. -Status readFile(const boost::filesystem::path& path, - std::function predicate, - bool log = true); +ReadResult readFile(const boost::filesystem::path& path, + std::function predicate, + bool log = true); /** * @brief Write text to disk. diff --git a/osquery/utils/status/status.h b/osquery/utils/status/status.h index 5b66b9fe81c5..5ad3dc68392f 100644 --- a/osquery/utils/status/status.h +++ b/osquery/utils/status/status.h @@ -75,7 +75,7 @@ class Status { * success or failure of an operation. On successful operations, the idiom * is for the message to be "OK" */ - std::string getMessage() const { + const std::string& getMessage() const { return message_; }