Add null checks to <dirent.h> functions.
Move all the new checks over to the existing __fortify_fatal.
Bug: http://b/67455242
Test: ran tests
Change-Id: Idb899c58c32d52d3b423caf1a91feb7defcba9b3
diff --git a/libc/Android.bp b/libc/Android.bp
index 2e5ec00..89d33b0 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -14,7 +14,7 @@
"bionic/siginterrupt.c",
"bionic/sigsetmask.c",
"stdio/fmemopen.cpp",
- "stdio/fread.c",
+ "stdio/fread.cpp",
"stdio/parsefloat.c",
"stdio/refill.c",
"stdio/stdio.cpp",
diff --git a/libc/bionic/dirent.cpp b/libc/bionic/dirent.cpp
index 6fd3842..37a2fa7 100644
--- a/libc/bionic/dirent.cpp
+++ b/libc/bionic/dirent.cpp
@@ -36,6 +36,7 @@
#include <sys/types.h>
#include <unistd.h>
+#include "private/bionic_fortify.h"
#include "private/ErrnoRestorer.h"
#include "private/ScopedPthreadMutexLocker.h"
@@ -56,6 +57,8 @@
long current_pos_;
};
+#define CHECK_DIR(d) if (d == nullptr) __fortify_fatal("%s: null DIR*", __FUNCTION__)
+
static DIR* __allocate_DIR(int fd) {
DIR* d = reinterpret_cast<DIR*>(malloc(sizeof(DIR)));
if (d == NULL) {
@@ -69,8 +72,9 @@
return d;
}
-int dirfd(DIR* dirp) {
- return dirp->fd_;
+int dirfd(DIR* d) {
+ CHECK_DIR(d);
+ return d->fd_;
}
DIR* fdopendir(int fd) {
@@ -93,6 +97,7 @@
}
static bool __fill_DIR(DIR* d) {
+ CHECK_DIR(d);
int rc = TEMP_FAILURE_RETRY(__getdents64(d->fd_, d->buff_, sizeof(d->buff_)));
if (rc <= 0) {
return false;
@@ -117,12 +122,15 @@
}
dirent* readdir(DIR* d) {
+ CHECK_DIR(d);
ScopedPthreadMutexLocker locker(&d->mutex_);
return __readdir_locked(d);
}
__strong_alias(readdir64, readdir);
int readdir_r(DIR* d, dirent* entry, dirent** result) {
+ CHECK_DIR(d);
+
ErrnoRestorer errno_restorer;
*result = NULL;
@@ -156,6 +164,8 @@
}
void rewinddir(DIR* d) {
+ CHECK_DIR(d);
+
ScopedPthreadMutexLocker locker(&d->mutex_);
lseek(d->fd_, 0, SEEK_SET);
d->available_bytes_ = 0;
@@ -163,6 +173,8 @@
}
void seekdir(DIR* d, long offset) {
+ CHECK_DIR(d);
+
ScopedPthreadMutexLocker locker(&d->mutex_);
off_t ret = lseek(d->fd_, offset, SEEK_SET);
if (ret != -1L) {
@@ -172,6 +184,8 @@
}
long telldir(DIR* d) {
+ CHECK_DIR(d);
+
return d->current_pos_;
}
diff --git a/libc/private/bionic_fortify.h b/libc/private/bionic_fortify.h
index 8591117..7f22963 100644
--- a/libc/private/bionic_fortify.h
+++ b/libc/private/bionic_fortify.h
@@ -26,6 +26,8 @@
* SUCH DAMAGE.
*/
+#pragma once
+
#include <poll.h> // For struct pollfd.
#include <stdarg.h>
#include <stdlib.h>
diff --git a/libc/stdio/fread.c b/libc/stdio/fread.cpp
similarity index 98%
rename from libc/stdio/fread.c
rename to libc/stdio/fread.cpp
index b6a3077..073f71a 100644
--- a/libc/stdio/fread.c
+++ b/libc/stdio/fread.cpp
@@ -79,7 +79,7 @@
__smakebuf(fp);
}
- char* dst = buf;
+ char* dst = static_cast<char*>(buf);
while (total > 0) {
/*
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index 02ea8f8..c728eec 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -39,7 +39,9 @@
#include <stdbool.h>
#include <wchar.h>
-#include <async_safe/log.h>
+#if defined(__cplusplus) // Until we fork all of stdio...
+#include "private/bionic_fortify.h"
+#endif
#include "wcio.h"
@@ -257,11 +259,6 @@
// Sanity check a FILE* for nullptr, so we can emit a message while crashing
// instead of doing a blind null-dereference.
-#define CHECK_FP(fp) \
- do { \
- if (__predict_false(fp == 0)) { \
- async_safe_fatal("invalid FILE* %p passed to %s", fp, __FUNCTION__); \
- } \
- } while (0)
+#define CHECK_FP(fp) if (fp == nullptr) __fortify_fatal("%s: null FILE*", __FUNCTION__)
#endif