summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Josh Gao <jmgao@google.com> 2018-08-30 15:36:01 -0700
committer Josh Gao <jmgao@google.com> 2018-08-30 18:26:27 -0700
commitf0029fcde5ccb85974ce8ef3c10bb457573d739e (patch)
treec4f2ba927dbf204e424f25df4f4f6b3ebee3f88f
parent34f83807383de4ef3d41cd6e34d52e08c05e783c (diff)
Use fdsan in FdFile.
Bug: http://b/113558485 Test: treehugger Change-Id: I681dc45fa0ba708130dca5d3232185440e4159f7
-rw-r--r--libartbase/base/unix_file/fd_file.cc83
-rw-r--r--libartbase/base/unix_file/fd_file.h27
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