diff options
Diffstat (limited to 'libc/stdio/stdio.cpp')
-rw-r--r-- | libc/stdio/stdio.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp index 1f08ea13d..050157bda 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* stdout = &__sF[1]; 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 @@ static FILE* __fopen(int fd, int flags) { 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 @@ FILE* freopen(const char* file, const char* mode, FILE* fp) { 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 @@ off64_t __sseek64(void* cookie, off64_t offset, int whence) { 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) { |