summaryrefslogtreecommitdiff
path: root/libc/stdio/stdio.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libc/stdio/stdio.cpp')
-rw-r--r--libc/stdio/stdio.cpp21
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) {