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/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index 1f08ea1..050157b 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -46,6 +46,8 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+#include <android/fdsan.h>
+
 #include <async_safe/log.h>
 
 #include "local.h"
@@ -54,6 +56,8 @@
 #include "private/ErrnoRestorer.h"
 #include "private/thread_private.h"
 
+extern "C" int ___close(int fd);
+
 #define ALIGNBYTES (sizeof(uintptr_t) - 1)
 #define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)
 
@@ -102,6 +106,19 @@
 FILE* stderr = &__sF[2];
 
 static pthread_mutex_t __stdio_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+
+static uint64_t __get_file_tag(FILE* fp) {
+  // Don't use a tag for the standard streams.
+  // They don't really own their file descriptors, because the values are well-known, and you're
+  // allowed to do things like `close(STDIN_FILENO); open("foo", O_RDONLY)` when single-threaded.
+  if (fp == stdin || fp == stderr || fp == stdout) {
+    return 0;
+  }
+
+  return android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_FILE,
+                                        reinterpret_cast<uint64_t>(fp));
+}
+
 struct glue __sglue = { nullptr, 3, __sF };
 static struct glue* lastglue = &__sglue;
 
@@ -219,6 +236,7 @@
   FILE* fp = __sfp();
   if (fp != nullptr) {
     fp->_file = fd;
+    android_fdsan_exchange_owner_tag(fd, 0, __get_file_tag(fp));
     fp->_flags = flags;
     fp->_cookie = fp;
     fp->_read = __sread;
@@ -373,6 +391,7 @@
 
   fp->_flags = flags;
   fp->_file = fd;
+  android_fdsan_exchange_owner_tag(fd, 0, __get_file_tag(fp));
   fp->_cookie = fp;
   fp->_read = __sread;
   fp->_write = __swrite;
@@ -518,7 +537,7 @@
 
 int __sclose(void* cookie) {
   FILE* fp = reinterpret_cast<FILE*>(cookie);
-  return close(fp->_file);
+  return android_fdsan_close_with_tag(fp->_file, __get_file_tag(fp));
 }
 
 static off64_t __seek_unlocked(FILE* fp, off64_t offset, int whence) {