Intercept base::File Open/Close
When a file descriptor is opened by the base::File, all calls to close(3) from the same dynamic library will hit a CHECK unless they are made from a whitelist of callsites belonging to base::File.
There is a handy protect_file_posix.gypi introduced to make it easy to enable on Chrome-for-Android.
This 'linker magic' is somewhat crazy, so:
1. it will be *removed *when crbug.com/424562 is fixed
2. it should only be used by a whitelist of binaries/libraries (in the opensource part: libchromeshell only)
BUG=424562
Review URL: https://codereview.chromium.org/676873004
Cr-Commit-Position: refs/heads/master@{#304592}
CrOS-Libchrome-Original-Commit: 45a0dc0b75b52e026eb15526ef441edc5dbe9ba5
diff --git a/base/files/file_posix.cc b/base/files/file_posix.cc
index 3d229e4..245ea6a 100644
--- a/base/files/file_posix.cc
+++ b/base/files/file_posix.cc
@@ -10,6 +10,7 @@
#include <unistd.h>
#include "base/files/file_path.h"
+#include "base/files/file_posix_hooks_internal.h"
#include "base/logging.h"
#include "base/metrics/sparse_histogram.h"
#include "base/posix/eintr_wrapper.h"
@@ -166,6 +167,14 @@
Time::kNanosecondsPerMicrosecond);
}
+// Default implementations of Protect/Unprotect hooks defined as weak symbols
+// where possible.
+void ProtectFileDescriptor(int fd) {
+}
+
+void UnprotectFileDescriptor(int fd) {
+}
+
// NaCl doesn't implement system calls to open files directly.
#if !defined(OS_NACL)
// TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here?
@@ -252,6 +261,7 @@
async_ = ((flags & FLAG_ASYNC) == FLAG_ASYNC);
error_details_ = FILE_OK;
file_.reset(descriptor);
+ ProtectFileDescriptor(descriptor);
}
#endif // !defined(OS_NACL)
@@ -264,6 +274,8 @@
}
PlatformFile File::TakePlatformFile() {
+ if (IsValid())
+ UnprotectFileDescriptor(GetPlatformFile());
return file_.release();
}
@@ -272,6 +284,7 @@
return;
base::ThreadRestrictions::AssertIOAllowed();
+ UnprotectFileDescriptor(GetPlatformFile());
file_.reset();
}
@@ -527,8 +540,10 @@
}
void File::SetPlatformFile(PlatformFile file) {
- DCHECK(!file_.is_valid());
+ CHECK(!file_.is_valid());
file_.reset(file);
+ if (file_.is_valid())
+ ProtectFileDescriptor(GetPlatformFile());
}
} // namespace base