fdsan: expose functions to get and interpret tags.
Make it easier to write tests in users of fdsan by exposing functions
to allow users to get and interpret the tags.
Test: bionic_unit_tests
Change-Id: Iafa9bcaeb5e4db230f3dfec6f483274f34602694
diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp
index 67b3a62..d877172 100644
--- a/libc/bionic/fdsan.cpp
+++ b/libc/bionic/fdsan.cpp
@@ -218,7 +218,7 @@
return result;
}
-static const char* __tag_to_type(uint64_t tag) {
+const char* android_fdsan_get_tag_type(uint64_t tag) {
uint64_t type = tag >> 56;
switch (type) {
case ANDROID_FDSAN_OWNER_TYPE_FILE:
@@ -253,7 +253,7 @@
}
}
-static uint64_t __tag_to_owner(uint64_t tag) {
+uint64_t android_fdsan_get_tag_value(uint64_t tag) {
// Lop off the most significant byte and sign extend.
return static_cast<uint64_t>(static_cast<int64_t>(tag << 8) >> 8);
}
@@ -266,10 +266,10 @@
uint64_t tag = expected_tag;
if (!atomic_compare_exchange_strong(&fde->close_tag, &tag, 0)) {
- const char* expected_type = __tag_to_type(expected_tag);
- uint64_t expected_owner = __tag_to_owner(expected_tag);
- const char* actual_type = __tag_to_type(tag);
- uint64_t actual_owner = __tag_to_owner(tag);
+ const char* expected_type = android_fdsan_get_tag_type(expected_tag);
+ uint64_t expected_owner = android_fdsan_get_tag_value(expected_tag);
+ const char* actual_type = android_fdsan_get_tag_type(tag);
+ uint64_t actual_owner = android_fdsan_get_tag_value(tag);
if (expected_tag && tag) {
fdsan_error(
"attempted to close file descriptor %d, "
@@ -299,6 +299,14 @@
return rc;
}
+uint64_t android_fdsan_get_owner_tag(int fd) {
+ FdEntry* fde = GetFdEntry(fd);
+ if (!fde) {
+ return 0;
+ }
+ return fde->close_tag;
+}
+
void android_fdsan_exchange_owner_tag(int fd, uint64_t expected_tag, uint64_t new_tag) {
FdEntry* fde = GetFdEntry(fd);
if (!fde) {
@@ -311,18 +319,18 @@
fdsan_error(
"failed to exchange ownership of file descriptor: fd %d is "
"owned by %s 0x%" PRIx64 ", was expected to be owned by %s 0x%" PRIx64,
- fd, __tag_to_type(tag), __tag_to_owner(tag), __tag_to_type(expected_tag),
- __tag_to_owner(expected_tag));
+ fd, android_fdsan_get_tag_type(tag), android_fdsan_get_tag_value(tag),
+ android_fdsan_get_tag_type(expected_tag), android_fdsan_get_tag_value(expected_tag));
} else if (expected_tag && !tag) {
fdsan_error(
"failed to exchange ownership of file descriptor: fd %d is "
"unowned, was expected to be owned by %s 0x%" PRIx64,
- fd, __tag_to_type(expected_tag), __tag_to_owner(expected_tag));
+ fd, android_fdsan_get_tag_type(expected_tag), android_fdsan_get_tag_value(expected_tag));
} else if (!expected_tag && tag) {
fdsan_error(
"failed to exchange ownership of file descriptor: fd %d is "
"owned by %s 0x%" PRIx64 ", was expected to be unowned",
- fd, __tag_to_type(tag), __tag_to_owner(tag));
+ fd, android_fdsan_get_tag_type(tag), android_fdsan_get_tag_value(tag));
} else if (!expected_tag && !tag) {
// This should never happen: our CAS failed, but expected == actual?
async_safe_fatal(
diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h
index 11f33fd..9c58e27 100644
--- a/libc/include/android/fdsan.h
+++ b/libc/include/android/fdsan.h
@@ -132,6 +132,25 @@
*/
int android_fdsan_close_with_tag(int fd, uint64_t tag) __INTRODUCED_IN_FUTURE __attribute__((__weak__));
+/*
+ * Get a file descriptor's current owner tag.
+ *
+ * Returns 0 for untagged and invalid file descriptors.
+ */
+uint64_t android_fdsan_get_owner_tag(int fd);
+
+/*
+ * Get an owner tag's string representation.
+ *
+ * The return value points to memory with static lifetime, do not attempt to modify it.
+ */
+const char* android_fdsan_get_tag_type(uint64_t tag);
+
+/*
+ * Get an owner tag's value, with the type masked off.
+ */
+uint64_t android_fdsan_get_tag_value(uint64_t tag);
+
enum android_fdsan_error_level {
// No errors.
ANDROID_FDSAN_ERROR_LEVEL_DISABLED,
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index 6d39812..f1eec3c 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1426,6 +1426,9 @@
android_fdsan_close_with_tag;
android_fdsan_create_owner_tag;
android_fdsan_exchange_owner_tag;
+ android_fdsan_get_owner_tag;
+ android_fdsan_get_tag_type;
+ android_fdsan_get_tag_value;
android_fdsan_get_error_level;
android_fdsan_set_error_level;
timespec_get;
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index 1cf48b1..4d538cd 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1347,6 +1347,9 @@
android_fdsan_close_with_tag;
android_fdsan_create_owner_tag;
android_fdsan_exchange_owner_tag;
+ android_fdsan_get_owner_tag;
+ android_fdsan_get_tag_type;
+ android_fdsan_get_tag_value;
android_fdsan_get_error_level;
android_fdsan_set_error_level;
timespec_get;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 135206e..0f5abc0 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1451,6 +1451,9 @@
android_fdsan_close_with_tag;
android_fdsan_create_owner_tag;
android_fdsan_exchange_owner_tag;
+ android_fdsan_get_owner_tag;
+ android_fdsan_get_tag_type;
+ android_fdsan_get_tag_value;
android_fdsan_get_error_level;
android_fdsan_set_error_level;
timespec_get;
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index a330a45..f14f731 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1410,6 +1410,9 @@
android_fdsan_close_with_tag;
android_fdsan_create_owner_tag;
android_fdsan_exchange_owner_tag;
+ android_fdsan_get_owner_tag;
+ android_fdsan_get_tag_type;
+ android_fdsan_get_tag_value;
android_fdsan_get_error_level;
android_fdsan_set_error_level;
timespec_get;
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index 1cf48b1..4d538cd 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1347,6 +1347,9 @@
android_fdsan_close_with_tag;
android_fdsan_create_owner_tag;
android_fdsan_exchange_owner_tag;
+ android_fdsan_get_owner_tag;
+ android_fdsan_get_tag_type;
+ android_fdsan_get_tag_value;
android_fdsan_get_error_level;
android_fdsan_set_error_level;
timespec_get;
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index 7a2fe9a..d44001e 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1408,6 +1408,9 @@
android_fdsan_close_with_tag;
android_fdsan_create_owner_tag;
android_fdsan_exchange_owner_tag;
+ android_fdsan_get_owner_tag;
+ android_fdsan_get_tag_type;
+ android_fdsan_get_tag_value;
android_fdsan_get_error_level;
android_fdsan_set_error_level;
timespec_get;
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index 1cf48b1..4d538cd 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1347,6 +1347,9 @@
android_fdsan_close_with_tag;
android_fdsan_create_owner_tag;
android_fdsan_exchange_owner_tag;
+ android_fdsan_get_owner_tag;
+ android_fdsan_get_tag_type;
+ android_fdsan_get_tag_value;
android_fdsan_get_error_level;
android_fdsan_set_error_level;
timespec_get;