summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Kralevich <nnk@google.com>2012-11-30 15:15:58 -0800
committerRicardo Cerqueira <cyanogenmod@cerqueira.org>2012-12-04 10:21:17 +0000
commit837ff616a8b7458f2d66bffcfec5b43c5f9226d4 (patch)
tree7f83f9dddd23bb9cea33aed238c8b73a7359937b
parent3fa5ca8c673cd46fd4ee33fbc59891791bce5f71 (diff)
downloadbionic-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.h17
-rw-r--r--libc/private/logd.h1
-rw-r--r--libc/string/strchr.c15
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);
+}