diff options
author | 2018-08-30 15:36:01 -0700 | |
---|---|---|
committer | 2018-08-30 18:26:27 -0700 | |
commit | f0029fcde5ccb85974ce8ef3c10bb457573d739e (patch) | |
tree | c4f2ba927dbf204e424f25df4f4f6b3ebee3f88f | |
parent | 34f83807383de4ef3d41cd6e34d52e08c05e783c (diff) |
Use fdsan in FdFile.
Bug: http://b/113558485
Test: treehugger
Change-Id: I681dc45fa0ba708130dca5d3232185440e4159f7
-rw-r--r-- | libartbase/base/unix_file/fd_file.cc | 83 | ||||
-rw-r--r-- | libartbase/base/unix_file/fd_file.h | 27 |
2 files changed, 84 insertions, 26 deletions
diff --git a/libartbase/base/unix_file/fd_file.cc b/libartbase/base/unix_file/fd_file.cc index 9d5c70d688..d715670194 100644 --- a/libartbase/base/unix_file/fd_file.cc +++ b/libartbase/base/unix_file/fd_file.cc @@ -21,6 +21,10 @@ #include <sys/types.h> #include <unistd.h> +#if defined(__BIONIC__) +#include <android/fdsan.h> +#endif + #include <limits> #include <android-base/logging.h> @@ -36,6 +40,13 @@ namespace unix_file { +#if defined(__BIONIC__) +static uint64_t GetFdFileOwnerTag(FdFile* fd_file) { + return android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_ART_FDFILE, + reinterpret_cast<uint64_t>(fd_file)); +} +#endif + FdFile::FdFile(int fd, bool check_usage) : FdFile(fd, std::string(), check_usage) {} @@ -47,7 +58,13 @@ FdFile::FdFile(int fd, const std::string& path, bool check_usage, : guard_state_(check_usage ? GuardState::kBase : GuardState::kNoCheck), fd_(fd), file_path_(path), - read_only_mode_(read_only_mode) {} + read_only_mode_(read_only_mode) { +#if defined(__BIONIC__) + if (fd >= 0) { + android_fdsan_exchange_owner_tag(fd, 0, GetFdFileOwnerTag(this)); + } +#endif +} FdFile::FdFile(const std::string& path, int flags, mode_t mode, bool check_usage) { @@ -74,6 +91,20 @@ void FdFile::Destroy() { } } +FdFile::FdFile(FdFile&& other) + : guard_state_(other.guard_state_), + fd_(other.fd_), + file_path_(std::move(other.file_path_)), + read_only_mode_(other.read_only_mode_) { +#if defined(__BIONIC__) + if (fd_ >= 0) { + android_fdsan_exchange_owner_tag(fd_, GetFdFileOwnerTag(&other), GetFdFileOwnerTag(this)); + } +#endif + other.guard_state_ = GuardState::kClosed; + other.fd_ = -1; +} + FdFile& FdFile::operator=(FdFile&& other) { if (this == &other) { return *this; @@ -87,8 +118,14 @@ FdFile& FdFile::operator=(FdFile&& other) { fd_ = other.fd_; file_path_ = std::move(other.file_path_); read_only_mode_ = other.read_only_mode_; - other.Release(); // Release other. +#if defined(__BIONIC__) + if (fd_ >= 0) { + android_fdsan_exchange_owner_tag(fd_, GetFdFileOwnerTag(&other), GetFdFileOwnerTag(this)); + } +#endif + other.guard_state_ = GuardState::kClosed; + other.fd_ = -1; return *this; } @@ -96,6 +133,39 @@ FdFile::~FdFile() { Destroy(); } +int FdFile::Release() { + int tmp_fd = fd_; + fd_ = -1; + guard_state_ = GuardState::kNoCheck; +#if defined(__BIONIC__) + if (tmp_fd >= 0) { + android_fdsan_exchange_owner_tag(tmp_fd, GetFdFileOwnerTag(this), 0); + } +#endif + return tmp_fd; +} + +void FdFile::Reset(int fd, bool check_usage) { + CHECK_NE(fd, fd_); + + if (fd_ != -1) { + Destroy(); + } + fd_ = fd; + +#if defined(__BIONIC__) + if (fd_ >= 0) { + android_fdsan_exchange_owner_tag(fd_, 0, GetFdFileOwnerTag(this)); + } +#endif + + if (check_usage) { + guard_state_ = fd == -1 ? GuardState::kNoCheck : GuardState::kBase; + } else { + guard_state_ = GuardState::kNoCheck; + } +} + void FdFile::moveTo(GuardState target, GuardState warn_threshold, const char* warning) { if (kCheckSafeUsage) { if (guard_state_ < GuardState::kNoCheck) { @@ -131,6 +201,11 @@ bool FdFile::Open(const std::string& path, int flags, mode_t mode) { if (fd_ == -1) { return false; } + +#if defined(__BIONIC__) + android_fdsan_exchange_owner_tag(fd_, 0, GetFdFileOwnerTag(this)); +#endif + file_path_ = path; if (kCheckSafeUsage && (flags & (O_RDWR | O_CREAT | O_WRONLY)) != 0) { // Start in the base state (not flushed, not closed). @@ -144,7 +219,11 @@ bool FdFile::Open(const std::string& path, int flags, mode_t mode) { } int FdFile::Close() { +#if defined(__BIONIC__) + int result = android_fdsan_close_with_tag(fd_, GetFdFileOwnerTag(this)); +#else int result = close(fd_); +#endif // Test here, so the file is closed and not leaked. if (kCheckSafeUsage) { diff --git a/libartbase/base/unix_file/fd_file.h b/libartbase/base/unix_file/fd_file.h index 54d84c4db3..e362ed13ce 100644 --- a/libartbase/base/unix_file/fd_file.h +++ b/libartbase/base/unix_file/fd_file.h @@ -46,37 +46,16 @@ class FdFile : public RandomAccessFile { FdFile(const std::string& path, int flags, mode_t mode, bool checkUsage); // Move constructor. - FdFile(FdFile&& other) - : guard_state_(other.guard_state_), - fd_(other.fd_), - file_path_(std::move(other.file_path_)), - read_only_mode_(other.read_only_mode_) { - other.Release(); // Release the src. - } + FdFile(FdFile&& other); // Move assignment operator. FdFile& operator=(FdFile&& other); // Release the file descriptor. This will make further accesses to this FdFile invalid. Disables // all further state checking. - int Release() { - int tmp_fd = fd_; - fd_ = -1; - guard_state_ = GuardState::kNoCheck; - return tmp_fd; - } + int Release(); - void Reset(int fd, bool check_usage) { - if (fd_ != -1 && fd_ != fd) { - Destroy(); - } - fd_ = fd; - if (check_usage) { - guard_state_ = fd == -1 ? GuardState::kNoCheck : GuardState::kBase; - } else { - guard_state_ = GuardState::kNoCheck; - } - } + void Reset(int fd, bool check_usage); // Destroys an FdFile, closing the file descriptor if Close hasn't already // been called. (If you care about the return value of Close, call it |