diff options
author | Nick Kralevich <nnk@google.com> | 2012-11-30 15:15:58 -0800 |
---|---|---|
committer | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2012-12-04 10:21:17 +0000 |
commit | 837ff616a8b7458f2d66bffcfec5b43c5f9226d4 (patch) | |
tree | 7f83f9dddd23bb9cea33aed238c8b73a7359937b | |
parent | 3fa5ca8c673cd46fd4ee33fbc59891791bce5f71 (diff) | |
download | bionic-837ff616a8b7458f2d66bffcfec5b43c5f9226d4.zip bionic-837ff616a8b7458f2d66bffcfec5b43c5f9226d4.tar.gz bionic-837ff616a8b7458f2d66bffcfec5b43c5f9226d4.tar.bz2 |
FORTIFY_SOURCE: fortify strchr
Detect when strchr reads off the end of a buffer.
Change-Id: I0e952eedcff5c36d646a9c3bc4e1337b959224f2
-rw-r--r-- | libc/include/string.h | 17 | ||||
-rw-r--r-- | libc/private/logd.h | 1 | ||||
-rw-r--r-- | 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 06e2284..32b9310 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 c81a91a..26878ba 100644 --- a/libc/private/logd.h +++ b/libc/private/logd.h @@ -29,6 +29,7 @@ #define _ANDROID_BIONIC_LOGD_H #include <stdarg.h> +#include <stdint.h> #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 9b4332c..44516ef 100644 --- a/libc/string/strchr.c +++ b/libc/string/strchr.c @@ -29,11 +29,17 @@ */ #include <string.h> +#include <private/logd.h> 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); +} |