summaryrefslogtreecommitdiffstats
path: root/libc/include/string.h
diff options
context:
space:
mode:
authorNick Kralevich <nnk@google.com>2013-06-17 14:49:19 -0700
committerNick Kralevich <nnk@google.com>2013-06-18 12:14:20 -0700
commit16d1af167f8e36a9aa4a07ae77034ad519b00463 (patch)
tree61abe872a5f2ebebc4fe15205a77158bc8372ec2 /libc/include/string.h
parentb24c0637d06fe0980b9e13a8d0c3e6f4dbda9cd5 (diff)
downloadbionic-16d1af167f8e36a9aa4a07ae77034ad519b00463.zip
bionic-16d1af167f8e36a9aa4a07ae77034ad519b00463.tar.gz
bionic-16d1af167f8e36a9aa4a07ae77034ad519b00463.tar.bz2
libc: add limited FORTIFY_SOURCE support for clang
In 829c089f83ddee37203b52bcb294867a9ae7bdbc, we disabled all FORTIFY_SOURCE support when compiling under clang. At the time, we didn't have proper test cases, and couldn't easily create targeted clang tests. This change re-enables FORTIFY_SOURCE support under clang for a limited set of functions, where we have explicit unittests available. The functions are: * memcpy * memmove * strcpy * strncpy * strcat * strncat * memset * strlen (with modifications) * strchr (with modifications) * strrchr (with modifications) It may be possible, in the future, to enable other functions. However, I need to write unittests first. For strlen, strchr, and strrchr, clang unconditionally calls the fortified version of the relevant function. If it doesn't know the size of the buffer it's dealing with, it passes in ((size_t) -1), which is the largest possible size_t. I added two new clang specific unittest files, primarily copied from fortify?_test.cpp. I've also rebuild the entire system with these changes, and didn't observe any obvious problems. Change-Id: If12a15089bb0ffe93824b485290d05b14355fcaa
Diffstat (limited to 'libc/include/string.h')
-rw-r--r--libc/include/string.h22
1 files changed, 16 insertions, 6 deletions
diff --git a/libc/include/string.h b/libc/include/string.h
index 3c9fc21..ac31f7d 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -91,7 +91,7 @@ __errordecl(__memcpy_dest_size_error, "memcpy called with size bigger than desti
__errordecl(__memcpy_src_size_error, "memcpy called with size bigger than source");
__BIONIC_FORTIFY_INLINE
-void *memcpy (void* __restrict dest, const void* __restrict src, size_t copy_amount) {
+void* memcpy(void* __restrict dest, const void* __restrict src, size_t copy_amount) {
char *d = (char *) dest;
const char *s = (const char *) src;
size_t s_len = __builtin_object_size(s, 0);
@@ -109,19 +109,19 @@ void *memcpy (void* __restrict dest, const void* __restrict src, size_t copy_amo
}
__BIONIC_FORTIFY_INLINE
-void *memmove (void *dest, const void *src, size_t len) {
+void* memmove(void *dest, const void *src, size_t len) {
return __builtin___memmove_chk(dest, src, len, __builtin_object_size (dest, 0));
}
__BIONIC_FORTIFY_INLINE
-char *strcpy(char* __restrict dest, const char* __restrict src) {
+char* strcpy(char* __restrict dest, const char* __restrict src) {
return __builtin___strcpy_chk(dest, src, __bos(dest));
}
__errordecl(__strncpy_error, "strncpy called with size bigger than buffer");
__BIONIC_FORTIFY_INLINE
-char *strncpy(char* __restrict dest, const char* __restrict src, size_t n) {
+char* strncpy(char* __restrict dest, const char* __restrict src, size_t n) {
size_t bos = __bos(dest);
if (__builtin_constant_p(n) && (n > bos)) {
__strncpy_error();
@@ -130,7 +130,7 @@ char *strncpy(char* __restrict dest, const char* __restrict src, size_t n) {
}
__BIONIC_FORTIFY_INLINE
-char *strcat(char* __restrict dest, const char* __restrict src) {
+char* strcat(char* __restrict dest, const char* __restrict src) {
return __builtin___strcat_chk(dest, src, __bos(dest));
}
@@ -140,10 +140,11 @@ char *strncat(char* __restrict dest, const char* __restrict src, size_t n) {
}
__BIONIC_FORTIFY_INLINE
-void *memset (void *s, int c, size_t n) {
+void* memset(void *s, int c, size_t n) {
return __builtin___memset_chk(s, c, n, __builtin_object_size (s, 0));
}
+#if !defined(__clang__)
extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t)
__asm__(__USER_LABEL_PREFIX__ "strlcpy");
__errordecl(__strlcpy_error, "strlcpy called with size bigger than buffer");
@@ -172,7 +173,9 @@ size_t strlcpy(char* __restrict dest, const char* __restrict src, size_t size) {
return __strlcpy_chk(dest, src, size, bos);
}
+#endif /* !defined(__clang__) */
+#if !defined(__clang__)
extern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t)
__asm__(__USER_LABEL_PREFIX__ "strlcat");
__errordecl(__strlcat_error, "strlcat called with size bigger than buffer");
@@ -202,11 +205,13 @@ size_t strlcat(char* __restrict dest, const char* __restrict src, size_t size) {
return __strlcat_chk(dest, src, size, bos);
}
+#endif /* !defined(__clang__) */
__BIONIC_FORTIFY_INLINE
size_t strlen(const char *s) {
size_t bos = __bos(s);
+#if !defined(__clang__)
// Compiler doesn't know destination size. Don't call __strlen_chk
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
return __builtin_strlen(s);
@@ -216,6 +221,7 @@ size_t strlen(const char *s) {
if (__builtin_constant_p(slen)) {
return slen;
}
+#endif /* !defined(__clang__) */
return __strlen_chk(s, bos);
}
@@ -226,6 +232,7 @@ __BIONIC_FORTIFY_INLINE
char* strchr(const char *s, int c) {
size_t bos = __bos(s);
+#if !defined(__clang__)
// Compiler doesn't know destination size. Don't call __strchr_chk
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
return __builtin_strchr(s, c);
@@ -235,6 +242,7 @@ char* strchr(const char *s, int c) {
if (__builtin_constant_p(slen) && (slen < bos)) {
return __builtin_strchr(s, c);
}
+#endif /* !defined(__clang__) */
return __strchr_chk(s, c, bos);
}
@@ -245,6 +253,7 @@ __BIONIC_FORTIFY_INLINE
char* strrchr(const char *s, int c) {
size_t bos = __bos(s);
+#if !defined(__clang__)
// Compiler doesn't know destination size. Don't call __strrchr_chk
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
return __builtin_strrchr(s, c);
@@ -254,6 +263,7 @@ char* strrchr(const char *s, int c) {
if (__builtin_constant_p(slen) && (slen < bos)) {
return __builtin_strrchr(s, c);
}
+#endif /* !defined(__clang__) */
return __strrchr_chk(s, c, bos);
}