From 049e58369c37fdeacd0380a6bf1e078d9baf819f Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Fri, 30 Nov 2012 15:15:58 -0800 Subject: [PATCH] FORTIFY_SOURCE: fortify strchr Detect when strchr reads off the end of a buffer. Change-Id: I0e952eedcff5c36d646a9c3bc4e1337b959224f2 --- libc/include/string.h | 17 +++++++++++++++++ libc/private/logd.h | 1 + libc/string/strchr.c | 15 +++++++++++++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/libc/include/string.h b/libc/include/string.h index 06e22841b..32b931019 100644 --- a/libc/include/string.h +++ b/libc/include/string.h @@ -224,6 +224,23 @@ size_t strlen(const char *s) { return __strlen_chk(s, bos); } +__purefunc extern char* __strchr_real(const char *, int) + __asm__(__USER_LABEL_PREFIX__ "strchr"); +extern char* __strchr_chk(const char *, int, size_t); + +__BIONIC_FORTIFY_INLINE +char* strchr(const char *s, int c) { + size_t bos = __builtin_object_size(s, 0); + + // Compiler doesn't know destination size. Don't call __strchr_chk + if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { + return __strchr_real(s, c); + } + + return __strchr_chk(s, c, bos); +} + + #endif /* defined(__BIONIC_FORTIFY_INLINE) */ __END_DECLS diff --git a/libc/private/logd.h b/libc/private/logd.h index c81a91a1c..26878ba61 100644 --- a/libc/private/logd.h +++ b/libc/private/logd.h @@ -29,6 +29,7 @@ #define _ANDROID_BIONIC_LOGD_H #include +#include #define BIONIC_EVENT_MEMCPY_BUFFER_OVERFLOW 80100 #define BIONIC_EVENT_STRCAT_BUFFER_OVERFLOW 80105 diff --git a/libc/string/strchr.c b/libc/string/strchr.c index 9b4332c7e..44516efd1 100644 --- a/libc/string/strchr.c +++ b/libc/string/strchr.c @@ -29,11 +29,17 @@ */ #include +#include char * -strchr(const char *p, int ch) +__strchr_chk(const char *p, int ch, size_t s_len) { - for (;; ++p) { + for (;; ++p, s_len--) { + if (s_len == 0) { + __libc_android_log_print(ANDROID_LOG_FATAL, "libc", + "*** FORTIFY_SOURCE strchr read beyond buffer ***\n"); + abort(); + } if (*p == (char) ch) return((char *)p); if (!*p) @@ -41,3 +47,8 @@ strchr(const char *p, int ch) } /* NOTREACHED */ } + +char * +strchr(const char *p, int ch) { + return __strchr_chk(p, ch, (size_t) -1); +}