Introduce api to track fd ownership in libc.

Add two functions to allow objects that own a file descriptor to
enforce that only they can close their file descriptor.

Use them in FILE* and DIR*.

Bug: http://b/110100358
Test: bionic_unit_tests
Test: aosp/master boots without errors
Test: treehugger
Change-Id: Iecd6e8b26c62217271e0822dc3d2d7888b091a45
diff --git a/tests/Android.bp b/tests/Android.bp
index b5efb8c..ccd1126 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -81,6 +81,7 @@
         "error_test.cpp",
         "eventfd_test.cpp",
         "fcntl_test.cpp",
+        "fdsan_test.cpp",
         "fenv_test.cpp",
         "float_test.cpp",
         "ftw_test.cpp",
diff --git a/tests/fdsan_test.cpp b/tests/fdsan_test.cpp
new file mode 100644
index 0000000..99f36aa
--- /dev/null
+++ b/tests/fdsan_test.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "BionicDeathTest.h"
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include <unordered_map>
+
+#if defined(__BIONIC__)
+#include <android/fdsan.h>
+#endif
+
+#define FDSAN_TEST(test_name) TEST_F(FdsanTest, test_name)
+#define EXPECT_FDSAN_DEATH(expression, regex)                                                \
+  EXPECT_DEATH((android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_FATAL), expression), \
+               (regex))
+
+struct FdsanTest : public ::testing::Test {
+  void SetUp() override {
+#if defined(__BIONIC__)
+    // The bionic unit test running forks for each test by default, which turns
+    // fdsan off as a side-effect, so we need to turn it back on.
+    android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_FATAL);
+#endif
+  }
+};
+
+TEST_F(FdsanTest, unowned_untagged_close) {
+#if defined(__BIONIC__)
+  int fd = open("/dev/null", O_RDONLY);
+  ASSERT_EQ(0, close(fd));
+#endif
+}
+
+TEST_F(FdsanTest, unowned_tagged_close) {
+#if defined(__BIONIC__)
+  int fd = open("/dev/null", O_RDONLY);
+  ASSERT_EQ(0, android_fdsan_close_with_tag(fd, 0));
+#endif
+}
+
+TEST_F(FdsanTest, unowned_improperly_tagged_close) {
+#if defined(__BIONIC__)
+  int fd = open("/dev/null", O_RDONLY);
+  EXPECT_FDSAN_DEATH(android_fdsan_close_with_tag(fd, 0xdeadbeef), "actually unowned");
+#endif
+}
+
+TEST_F(FdsanTest, unowned_incorrect_exchange) {
+#if defined(__BIONIC__)
+  int fd = open("/dev/null", O_RDONLY);
+  EXPECT_FDSAN_DEATH(android_fdsan_exchange_owner_tag(fd, 0xbadc0de, 0xdeadbeef),
+                     "failed to exchange");
+#endif
+}
+
+TEST_F(FdsanTest, owned_untagged_close) {
+#if defined(__BIONIC__)
+  int fd = open("/dev/null", O_RDONLY);
+  android_fdsan_exchange_owner_tag(fd, 0, 0xdeadbeef);
+  EXPECT_FDSAN_DEATH(close(fd), "expected to be unowned, actually owned");
+#endif
+}
+
+TEST_F(FdsanTest, owned_tagged_close) {
+#if defined(__BIONIC__)
+  int fd = open("/dev/null", O_RDONLY);
+  android_fdsan_exchange_owner_tag(fd, 0, 0xdeadbeef);
+  ASSERT_EQ(0, android_fdsan_close_with_tag(fd, 0xdeadbeef));
+#endif
+}
+
+TEST_F(FdsanTest, owned_improperly_tagged_close) {
+#if defined(__BIONIC__)
+  int fd = open("/dev/null", O_RDONLY);
+  android_fdsan_exchange_owner_tag(fd, 0, 0xdeadbeef);
+  EXPECT_FDSAN_DEATH(android_fdsan_close_with_tag(fd, 0xdeadc0de), "expected to be owned");
+#endif
+}
+
+TEST_F(FdsanTest, owned_incorrect_exchange) {
+#if defined(__BIONIC__)
+  int fd = open("/dev/null", O_RDONLY);
+  android_fdsan_exchange_owner_tag(fd, 0, 0xdeadbeef);
+  EXPECT_FDSAN_DEATH(android_fdsan_exchange_owner_tag(fd, 0xbadc0de, 0xdeadbeef),
+                     "failed to exchange");
+#endif
+}
+
+TEST_F(FdsanTest, fopen) {
+#if defined(__BIONIC__)
+  FILE* f = fopen("/dev/null", "r");
+  ASSERT_TRUE(f);
+  EXPECT_FDSAN_DEATH(close(fileno(f)), "actually owned by FILE");
+#endif
+}
+
+TEST_F(FdsanTest, closedir) {
+#if defined(__BIONIC__)
+  DIR* dir = opendir("/dev/");
+  ASSERT_TRUE(dir);
+  EXPECT_FDSAN_DEATH(close(dirfd(dir)), "actually owned by DIR");
+#endif
+}
+
+TEST_F(FdsanTest, overflow) {
+#if defined(__BIONIC__)
+  std::unordered_map<int, uint64_t> fds;
+  for (int i = 0; i < 4096; ++i) {
+    int fd = open("/dev/null", O_RDONLY);
+    auto tag = 0xdead00000000ULL | i;
+    android_fdsan_exchange_owner_tag(fd, 0, tag);
+    fds[fd] = tag;
+  }
+
+  for (auto [fd, tag] : fds) {
+    android_fdsan_close_with_tag(fd, tag);
+  }
+#endif
+}
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 6282ec3..d499ddb 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -192,12 +192,6 @@
   errno = 0;
   ASSERT_EQ(getdelim(&buffer, NULL, ' ', fp), -1);
   ASSERT_EQ(EINVAL, errno);
-
-  // The underlying fd can't be closed.
-  ASSERT_EQ(0, close(fileno(fp)));
-  errno = 0;
-  ASSERT_EQ(getdelim(&buffer, &buffer_length, ' ', fp), -1);
-  ASSERT_EQ(EBADF, errno);
   fclose(fp);
 }
 
@@ -268,12 +262,6 @@
   errno = 0;
   ASSERT_EQ(getline(&buffer, NULL, fp), -1);
   ASSERT_EQ(EINVAL, errno);
-
-  // The underlying fd can't be closed.
-  ASSERT_EQ(0, close(fileno(fp)));
-  errno = 0;
-  ASSERT_EQ(getline(&buffer, &buffer_length, fp), -1);
-  ASSERT_EQ(EBADF, errno);
   fclose(fp);
 }
 
@@ -869,14 +857,16 @@
 TEST(STDIO_TEST, fprintf_failures_7229520) {
   // http://b/7229520
   FILE* fp;
+  int fd_rdonly = open("/dev/null", O_RDONLY);
+  ASSERT_NE(-1, fd_rdonly);
 
   // Unbuffered case where the fprintf(3) itself fails.
   ASSERT_NE(nullptr, fp = tmpfile());
   setbuf(fp, NULL);
   ASSERT_EQ(4, fprintf(fp, "epic"));
-  ASSERT_EQ(0, close(fileno(fp)));
+  ASSERT_NE(-1, dup2(fd_rdonly, fileno(fp)));
   ASSERT_EQ(-1, fprintf(fp, "fail"));
-  ASSERT_EQ(-1, fclose(fp));
+  ASSERT_EQ(0, fclose(fp));
 
   // Buffered case where we won't notice until the fclose(3).
   // It's likely this is what was actually seen in http://b/7229520,
@@ -884,7 +874,7 @@
   // disappointment. Remember to check fclose(3)'s return value, kids!
   ASSERT_NE(nullptr, fp = tmpfile());
   ASSERT_EQ(4, fprintf(fp, "epic"));
-  ASSERT_EQ(0, close(fileno(fp)));
+  ASSERT_NE(-1, dup2(fd_rdonly, fileno(fp)));
   ASSERT_EQ(4, fprintf(fp, "fail"));
   ASSERT_EQ(-1, fclose(fp));
 }
@@ -1916,7 +1906,6 @@
   AssertCloseOnExec(fileno(fp), true);
 
   fclose(fp);
-  close(fd);
 }
 
 TEST(STDIO_TEST, freopen_CLOEXEC) {