From 9a4d305340e6ce2fc6c3f371f2d7ede446f8c6d4 Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Mon, 3 Dec 2012 10:36:13 -0800 Subject: [PATCH] FORTIFY_SOURCE: fortify strrchr This change compliments 049e58369c37fdeacd0380a6bf1e078d9baf819f Change-Id: I27d015d70a520713c7472558a3c427f546d36ee4 --- libc/include/string.h | 16 ++++++++++++++++ libc/string/strrchr.c | 16 ++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/libc/include/string.h b/libc/include/string.h index 32b931019..2ed74e838 100644 --- a/libc/include/string.h +++ b/libc/include/string.h @@ -240,6 +240,22 @@ char* strchr(const char *s, int c) { return __strchr_chk(s, c, bos); } +__purefunc extern char* __strrchr_real(const char *, int) + __asm__(__USER_LABEL_PREFIX__ "strrchr"); +extern char* __strrchr_chk(const char *, int, size_t); + +__BIONIC_FORTIFY_INLINE +char* strrchr(const char *s, int c) { + size_t bos = __builtin_object_size(s, 0); + + // Compiler doesn't know destination size. Don't call __strrchr_chk + if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { + return __strrchr_real(s, c); + } + + return __strrchr_chk(s, c, bos); +} + #endif /* defined(__BIONIC_FORTIFY_INLINE) */ diff --git a/libc/string/strrchr.c b/libc/string/strrchr.c index 10c07e63c..fc3dc4ed7 100644 --- a/libc/string/strrchr.c +++ b/libc/string/strrchr.c @@ -29,13 +29,19 @@ */ #include +#include char * -strrchr(const char *p, int ch) +__strrchr_chk(const char *p, int ch, size_t s_len) { char *save; - for (save = NULL;; ++p) { + for (save = NULL;; ++p, s_len--) { + if (s_len == 0) { + __libc_android_log_print(ANDROID_LOG_FATAL, "libc", + "*** FORTIFY_SOURCE strrchr read beyond buffer ***\n"); + abort(); + } if (*p == (char) ch) save = (char *)p; if (!*p) @@ -43,3 +49,9 @@ strrchr(const char *p, int ch) } /* NOTREACHED */ } + +char * +strrchr(const char *p, int ch) +{ + return __strrchr_chk(p, ch, (size_t) -1); +}