summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libc/include/fcntl.h4
-rw-r--r--libc/include/stdio.h4
-rw-r--r--libc/include/string.h22
-rw-r--r--libc/include/strings.h4
-rw-r--r--libc/include/sys/cdefs.h5
-rw-r--r--libc/include/sys/stat.h4
-rw-r--r--tests/Android.mk24
-rw-r--r--tests/fortify1_test.cpp26
-rw-r--r--tests/fortify1_test_clang.cpp298
-rw-r--r--tests/fortify2_test.cpp26
-rw-r--r--tests/fortify2_test_clang.cpp171
11 files changed, 571 insertions, 17 deletions
diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h
index 67fd597..94322fd 100644
--- a/libc/include/fcntl.h
+++ b/libc/include/fcntl.h
@@ -49,7 +49,7 @@ extern int unlinkat(int dirfd, const char *pathname, int flags);
extern int fcntl(int fd, int command, ...);
extern int creat(const char* path, mode_t mode);
-#if defined(__BIONIC_FORTIFY)
+#if defined(__BIONIC_FORTIFY) && !defined(__clang__)
__errordecl(__creat_error, "called with O_CREAT, but missing mode");
__errordecl(__too_many_args_error, "too many arguments");
extern int __open_real(const char *pathname, int flags, ...)
@@ -98,7 +98,7 @@ int openat(int dirfd, const char *pathname, int flags, ...) {
return __openat_real(dirfd, pathname, flags, __builtin_va_arg_pack());
}
-#endif /* defined(__BIONIC_FORTIFY) */
+#endif /* defined(__BIONIC_FORTIFY) && !defined(__clang__) */
__END_DECLS
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index 154a86c..511bcd2 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -450,7 +450,7 @@ int vfdprintf(int, const char*, __va_list)
__END_DECLS
#endif /* _GNU_SOURCE */
-#if defined(__BIONIC_FORTIFY)
+#if defined(__BIONIC_FORTIFY) && !defined(__clang__)
__BEGIN_DECLS
@@ -523,6 +523,6 @@ char *fgets(char *dest, int size, FILE *stream)
__END_DECLS
-#endif /* defined(__BIONIC_FORTIFY) */
+#endif /* defined(__BIONIC_FORTIFY) && !defined(__clang__) */
#endif /* _STDIO_H_ */
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);
}
diff --git a/libc/include/strings.h b/libc/include/strings.h
index e72798b..faa12a4 100644
--- a/libc/include/strings.h
+++ b/libc/include/strings.h
@@ -50,12 +50,12 @@ char *index(const char *, int);
int strcasecmp(const char *, const char *);
int strncasecmp(const char *, const char *, size_t);
-#if defined(__BIONIC_FORTIFY)
+#if defined(__BIONIC_FORTIFY) && !defined(__clang__)
__BIONIC_FORTIFY_INLINE
void bzero (void *s, size_t n) {
__builtin___memset_chk(s, '\0', n, __builtin_object_size (s, 0));
}
-#endif /* defined(__BIONIC_FORTIFY) */
+#endif /* defined(__BIONIC_FORTIFY) && !defined(__clang__) */
__END_DECLS
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 78513e3..c7fb9de 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -524,7 +524,7 @@
#define __BIONIC__ 1
#include <android/api-level.h>
-#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 && !defined(__clang__)
+#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
#define __BIONIC_FORTIFY 1
#if _FORTIFY_SOURCE == 2
#define __bos(s) __builtin_object_size((s), 1)
@@ -535,8 +535,7 @@
#define __BIONIC_FORTIFY_INLINE \
extern inline \
__attribute__ ((always_inline)) \
- __attribute__ ((gnu_inline)) \
- __attribute__ ((artificial))
+ __attribute__ ((gnu_inline))
#endif
#define __BIONIC_FORTIFY_UNKNOWN_SIZE ((size_t) -1)
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index da49e1a..cf0d82d 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -129,7 +129,7 @@ extern int lstat(const char *, struct stat *);
extern int mknod(const char *, mode_t, dev_t);
extern mode_t umask(mode_t);
-#if defined(__BIONIC_FORTIFY)
+#if defined(__BIONIC_FORTIFY) && !defined(__clang__)
extern mode_t __umask_chk(mode_t);
extern mode_t __umask_real(mode_t)
@@ -146,7 +146,7 @@ mode_t umask(mode_t mode) {
}
return __umask_chk(mode);
}
-#endif /* defined(__BIONIC_FORTIFY) */
+#endif /* defined(__BIONIC_FORTIFY) && !defined(__clang__) */
#define stat64 stat
diff --git a/tests/Android.mk b/tests/Android.mk
index c65d20c..fe794c4 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -96,6 +96,7 @@ LOCAL_CFLAGS += $(test_c_flags)
LOCAL_LDFLAGS += $(test_dynamic_ldflags)
LOCAL_SHARED_LIBRARIES += libdl
LOCAL_SRC_FILES := $(test_src_files) $(test_dynamic_src_files)
+LOCAL_WHOLE_STATIC_LIBRARIES := bionic-unit-tests-clang
include $(BUILD_NATIVE_TEST)
# Build tests for the device (with bionic's .a). Run with:
@@ -107,6 +108,7 @@ LOCAL_CFLAGS += $(test_c_flags)
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_SRC_FILES := $(test_src_files)
LOCAL_STATIC_LIBRARIES += libstlport_static libstdc++ libm libc
+LOCAL_WHOLE_STATIC_LIBRARIES := bionic-unit-tests-clang
include $(BUILD_NATIVE_TEST)
# -----------------------------------------------------------------------------
@@ -143,4 +145,26 @@ LOCAL_SRC_FILES := $(test_src_files) $(test_dynamic_src_files)
include $(BUILD_HOST_NATIVE_TEST)
endif
+# -----------------------------------------------------------------------------
+# Unit tests which depend on clang as the compiler
+# -----------------------------------------------------------------------------
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := fortify1_test_clang.cpp fortify2_test_clang.cpp
+LOCAL_MODULE := bionic-unit-tests-clang
+LOCAL_CLANG := true
+
+# -Wno-error=unused-parameter needed as
+# external/stlport/stlport/stl/_threads.c (included from
+# external/gtest/include/gtest/gtest.h) does not compile cleanly under
+# clang. TODO: fix this.
+LOCAL_CFLAGS += $(test_c_flags) -Wno-error=unused-parameter
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_C_INCLUDES += bionic \
+ bionic/libstdc++/include \
+ external/stlport/stlport \
+ external/gtest/include
+
+include $(BUILD_STATIC_LIBRARY)
+
endif # !BUILD_TINY_ANDROID
diff --git a/tests/fortify1_test.cpp b/tests/fortify1_test.cpp
index bbff000..be59a18 100644
--- a/tests/fortify1_test.cpp
+++ b/tests/fortify1_test.cpp
@@ -115,6 +115,32 @@ TEST(Fortify1_DeathTest, strcat_fortified) {
ASSERT_EXIT(strcat(buf, src), testing::KilledBySignal(SIGABRT), "");
}
+TEST(Fortify1_DeathTest, memmove_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[20];
+ strcpy(buf, "0123456789");
+ size_t n = atoi("10");
+ ASSERT_EXIT(memmove(buf + 11, buf, n), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify1_DeathTest, memcpy_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char bufa[10];
+ char bufb[10];
+ strcpy(bufa, "012345678");
+ size_t n = atoi("11");
+ ASSERT_EXIT(memcpy(bufb, bufa, n), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify1_DeathTest, strncpy_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char bufa[15];
+ char bufb[10];
+ strcpy(bufa, "01234567890123");
+ size_t n = strlen(bufa);
+ ASSERT_EXIT(strncpy(bufb, bufa, n), testing::KilledBySignal(SIGABRT), "");
+}
+
extern "C" char* __strncat_chk(char*, const char*, size_t, size_t);
extern "C" char* __strcat_chk(char*, const char*, size_t);
diff --git a/tests/fortify1_test_clang.cpp b/tests/fortify1_test_clang.cpp
new file mode 100644
index 0000000..2a1b8a7
--- /dev/null
+++ b/tests/fortify1_test_clang.cpp
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#undef _FORTIFY_SOURCE
+#define _FORTIFY_SOURCE 1
+
+#include <gtest/gtest.h>
+#include <string.h>
+
+#if __BIONIC__
+// We have to say "DeathTest" here so gtest knows to run this test (which exits)
+// in its own process.
+
+// multibyte target where we over fill (should fail)
+TEST(Fortify1_Clang_DeathTest, strcpy_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[10];
+ char *orig = strdup("0123456789");
+ ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGABRT), "");
+ free(orig);
+}
+
+// zero sized target with "\0" source (should fail)
+TEST(Fortify1_Clang_DeathTest, strcpy2_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[0];
+ char *orig = strdup("");
+ ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGABRT), "");
+ free(orig);
+}
+
+// zero sized target with longer source (should fail)
+TEST(Fortify1_Clang_DeathTest, strcpy3_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[0];
+ char *orig = strdup("1");
+ ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGABRT), "");
+ free(orig);
+}
+
+// one byte target with longer source (should fail)
+TEST(Fortify1_Clang_DeathTest, strcpy4_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[1];
+ char *orig = strdup("12");
+ ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGABRT), "");
+ free(orig);
+}
+
+TEST(Fortify1_Clang_DeathTest, strlen_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[10];
+ memcpy(buf, "0123456789", sizeof(buf));
+ ASSERT_EXIT(printf("%d", strlen(buf)), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify1_Clang_DeathTest, strchr_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[10];
+ memcpy(buf, "0123456789", sizeof(buf));
+ ASSERT_EXIT(printf("%s", strchr(buf, 'a')), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify1_Clang_DeathTest, strrchr_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[10];
+ memcpy(buf, "0123456789", sizeof(buf));
+ ASSERT_EXIT(printf("%s", strrchr(buf, 'a')), testing::KilledBySignal(SIGABRT), "");
+}
+#endif
+
+TEST(Fortify1_Clang_DeathTest, strncat_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[10];
+ size_t n = atoi("10"); // avoid compiler optimizations
+ strncpy(buf, "012345678", n);
+ ASSERT_EXIT(strncat(buf, "9", n), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify1_Clang_DeathTest, strncat2_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[10];
+ buf[0] = '\0';
+ size_t n = atoi("10"); // avoid compiler optimizations
+ ASSERT_EXIT(strncat(buf, "0123456789", n), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify1_Clang_DeathTest, strcat_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char src[11];
+ strcpy(src, "0123456789");
+ char buf[10];
+ buf[0] = '\0';
+ ASSERT_EXIT(strcat(buf, src), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify1_Clang_DeathTest, memmove_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[20];
+ strcpy(buf, "0123456789");
+ size_t n = atoi("10");
+ ASSERT_EXIT(memmove(buf + 11, buf, n), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify1_Clang_DeathTest, memcpy_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char bufa[10];
+ char bufb[10];
+ strcpy(bufa, "012345678");
+ size_t n = atoi("11");
+ ASSERT_EXIT(memcpy(bufb, bufa, n), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify1_Clang_DeathTest, strncpy_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char bufa[15];
+ char bufb[10];
+ strcpy(bufa, "01234567890123");
+ size_t n = strlen(bufa);
+ ASSERT_EXIT(strncpy(bufb, bufa, n), testing::KilledBySignal(SIGABRT), "");
+}
+
+extern "C" char* __strncat_chk(char*, const char*, size_t, size_t);
+extern "C" char* __strcat_chk(char*, const char*, size_t);
+
+TEST(Fortify1_Clang, strncat) {
+ char buf[10];
+ memset(buf, 'A', sizeof(buf));
+ buf[0] = 'a';
+ buf[1] = '\0';
+ char* res = __strncat_chk(buf, "01234", sizeof(buf) - strlen(buf) - 1, sizeof(buf));
+ ASSERT_EQ(buf, res);
+ ASSERT_EQ('a', buf[0]);
+ ASSERT_EQ('0', buf[1]);
+ ASSERT_EQ('1', buf[2]);
+ ASSERT_EQ('2', buf[3]);
+ ASSERT_EQ('3', buf[4]);
+ ASSERT_EQ('4', buf[5]);
+ ASSERT_EQ('\0', buf[6]);
+ ASSERT_EQ('A', buf[7]);
+ ASSERT_EQ('A', buf[8]);
+ ASSERT_EQ('A', buf[9]);
+}
+
+TEST(Fortify1_Clang, strncat2) {
+ char buf[10];
+ memset(buf, 'A', sizeof(buf));
+ buf[0] = 'a';
+ buf[1] = '\0';
+ char* res = __strncat_chk(buf, "0123456789", 5, sizeof(buf));
+ ASSERT_EQ(buf, res);
+ ASSERT_EQ('a', buf[0]);
+ ASSERT_EQ('0', buf[1]);
+ ASSERT_EQ('1', buf[2]);
+ ASSERT_EQ('2', buf[3]);
+ ASSERT_EQ('3', buf[4]);
+ ASSERT_EQ('4', buf[5]);
+ ASSERT_EQ('\0', buf[6]);
+ ASSERT_EQ('A', buf[7]);
+ ASSERT_EQ('A', buf[8]);
+ ASSERT_EQ('A', buf[9]);
+}
+
+TEST(Fortify1_Clang, strncat3) {
+ char buf[10];
+ memset(buf, 'A', sizeof(buf));
+ buf[0] = '\0';
+ char* res = __strncat_chk(buf, "0123456789", 5, sizeof(buf));
+ ASSERT_EQ(buf, res);
+ ASSERT_EQ('0', buf[0]);
+ ASSERT_EQ('1', buf[1]);
+ ASSERT_EQ('2', buf[2]);
+ ASSERT_EQ('3', buf[3]);
+ ASSERT_EQ('4', buf[4]);
+ ASSERT_EQ('\0', buf[5]);
+ ASSERT_EQ('A', buf[6]);
+ ASSERT_EQ('A', buf[7]);
+ ASSERT_EQ('A', buf[8]);
+ ASSERT_EQ('A', buf[9]);
+}
+
+TEST(Fortify1_Clang, strncat4) {
+ char buf[10];
+ memset(buf, 'A', sizeof(buf));
+ buf[9] = '\0';
+ char* res = __strncat_chk(buf, "", 5, sizeof(buf));
+ ASSERT_EQ(buf, res);
+ ASSERT_EQ('A', buf[0]);
+ ASSERT_EQ('A', buf[1]);
+ ASSERT_EQ('A', buf[2]);
+ ASSERT_EQ('A', buf[3]);
+ ASSERT_EQ('A', buf[4]);
+ ASSERT_EQ('A', buf[5]);
+ ASSERT_EQ('A', buf[6]);
+ ASSERT_EQ('A', buf[7]);
+ ASSERT_EQ('A', buf[8]);
+ ASSERT_EQ('\0', buf[9]);
+}
+
+TEST(Fortify1_Clang, strncat5) {
+ char buf[10];
+ memset(buf, 'A', sizeof(buf));
+ buf[0] = 'a';
+ buf[1] = '\0';
+ char* res = __strncat_chk(buf, "01234567", 8, sizeof(buf));
+ ASSERT_EQ(buf, res);
+ ASSERT_EQ('a', buf[0]);
+ ASSERT_EQ('0', buf[1]);
+ ASSERT_EQ('1', buf[2]);
+ ASSERT_EQ('2', buf[3]);
+ ASSERT_EQ('3', buf[4]);
+ ASSERT_EQ('4', buf[5]);
+ ASSERT_EQ('5', buf[6]);
+ ASSERT_EQ('6', buf[7]);
+ ASSERT_EQ('7', buf[8]);
+ ASSERT_EQ('\0', buf[9]);
+}
+
+TEST(Fortify1_Clang, strncat6) {
+ char buf[10];
+ memset(buf, 'A', sizeof(buf));
+ buf[0] = 'a';
+ buf[1] = '\0';
+ char* res = __strncat_chk(buf, "01234567", 9, sizeof(buf));
+ ASSERT_EQ(buf, res);
+ ASSERT_EQ('a', buf[0]);
+ ASSERT_EQ('0', buf[1]);
+ ASSERT_EQ('1', buf[2]);
+ ASSERT_EQ('2', buf[3]);
+ ASSERT_EQ('3', buf[4]);
+ ASSERT_EQ('4', buf[5]);
+ ASSERT_EQ('5', buf[6]);
+ ASSERT_EQ('6', buf[7]);
+ ASSERT_EQ('7', buf[8]);
+ ASSERT_EQ('\0', buf[9]);
+}
+
+
+TEST(Fortify1_Clang, strcat) {
+ char buf[10];
+ memset(buf, 'A', sizeof(buf));
+ buf[0] = 'a';
+ buf[1] = '\0';
+ char* res = __strcat_chk(buf, "01234", sizeof(buf));
+ ASSERT_EQ(buf, res);
+ ASSERT_EQ('a', buf[0]);
+ ASSERT_EQ('0', buf[1]);
+ ASSERT_EQ('1', buf[2]);
+ ASSERT_EQ('2', buf[3]);
+ ASSERT_EQ('3', buf[4]);
+ ASSERT_EQ('4', buf[5]);
+ ASSERT_EQ('\0', buf[6]);
+ ASSERT_EQ('A', buf[7]);
+ ASSERT_EQ('A', buf[8]);
+ ASSERT_EQ('A', buf[9]);
+}
+
+TEST(Fortify1_Clang, strcat2) {
+ char buf[10];
+ memset(buf, 'A', sizeof(buf));
+ buf[0] = 'a';
+ buf[1] = '\0';
+ char* res = __strcat_chk(buf, "01234567", sizeof(buf));
+ ASSERT_EQ(buf, res);
+ ASSERT_EQ('a', buf[0]);
+ ASSERT_EQ('0', buf[1]);
+ ASSERT_EQ('1', buf[2]);
+ ASSERT_EQ('2', buf[3]);
+ ASSERT_EQ('3', buf[4]);
+ ASSERT_EQ('4', buf[5]);
+ ASSERT_EQ('5', buf[6]);
+ ASSERT_EQ('6', buf[7]);
+ ASSERT_EQ('7', buf[8]);
+ ASSERT_EQ('\0', buf[9]);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t test_fortify_inline(char* buf) {
+ return __bos(buf);
+}
+
+TEST(Fortify1_Clang, fortify_inline) {
+ char buf[1024];
+ ASSERT_EQ(test_fortify_inline(buf), sizeof(buf));
+}
diff --git a/tests/fortify2_test.cpp b/tests/fortify2_test.cpp
index 874eb1d..b48a077 100644
--- a/tests/fortify2_test.cpp
+++ b/tests/fortify2_test.cpp
@@ -233,3 +233,29 @@ TEST(Fortify2_DeathTest, strcat_fortified) {
buf[0] = '\0';
ASSERT_EXIT(strcat(buf, src), testing::KilledBySignal(SIGABRT), "");
}
+
+TEST(Fortify2_DeathTest, memmove_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[20];
+ strcpy(buf, "0123456789");
+ size_t n = atoi("10");
+ ASSERT_EXIT(memmove(buf + 11, buf, n), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_DeathTest, memcpy_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char bufa[10];
+ char bufb[10];
+ strcpy(bufa, "012345678");
+ size_t n = atoi("11");
+ ASSERT_EXIT(memcpy(bufb, bufa, n), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_DeathTest, strncpy_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char bufa[15];
+ char bufb[10];
+ strcpy(bufa, "01234567890123");
+ size_t n = strlen(bufa);
+ ASSERT_EXIT(strncpy(bufb, bufa, n), testing::KilledBySignal(SIGABRT), "");
+}
diff --git a/tests/fortify2_test_clang.cpp b/tests/fortify2_test_clang.cpp
new file mode 100644
index 0000000..2abf85a
--- /dev/null
+++ b/tests/fortify2_test_clang.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#undef _FORTIFY_SOURCE
+#define _FORTIFY_SOURCE 2
+
+#include <gtest/gtest.h>
+#include <string.h>
+
+struct foo {
+ char empty[0];
+ char one[1];
+ char a[10];
+ char b[10];
+};
+
+// We have to say "DeathTest" here so gtest knows to run this test (which exits)
+// in its own process.
+TEST(Fortify2_Clang_DeathTest, strncat3_fortified2) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ foo myfoo;
+ memcpy(myfoo.a, "0123456789", sizeof(myfoo.a)); // unterminated string
+ myfoo.b[0] = '\0';
+ size_t n = atoi("10"); // avoid compiler optimizations
+ ASSERT_EXIT(strncat(myfoo.b, myfoo.a, n), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_Clang_DeathTest, strcat2_fortified2) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ foo myfoo;
+ memcpy(myfoo.a, "0123456789", sizeof(myfoo.a)); // unterminated string
+ myfoo.b[0] = '\0';
+ ASSERT_EXIT(strcat(myfoo.b, myfoo.a), testing::KilledBySignal(SIGABRT), "");
+}
+
+/*****************************************************************/
+/* TESTS BELOW HERE DUPLICATE TESTS FROM fortify1_test_clang.cpp */
+/*****************************************************************/
+
+#if __BIONIC__
+// multibyte target where we over fill (should fail)
+TEST(Fortify2_Clang_DeathTest, strcpy_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[10];
+ char *orig = strdup("0123456789");
+ ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGABRT), "");
+ free(orig);
+}
+
+// zero sized target with "\0" source (should fail)
+TEST(Fortify2_Clang_DeathTest, strcpy2_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[0];
+ char *orig = strdup("");
+ ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGABRT), "");
+ free(orig);
+}
+
+// zero sized target with longer source (should fail)
+TEST(Fortify2_Clang_DeathTest, strcpy3_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[0];
+ char *orig = strdup("1");
+ ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGABRT), "");
+ free(orig);
+}
+
+// one byte target with longer source (should fail)
+TEST(Fortify2_Clang_DeathTest, strcpy4_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[1];
+ char *orig = strdup("12");
+ ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGABRT), "");
+ free(orig);
+}
+
+TEST(Fortify2_Clang_DeathTest, strlen_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[10];
+ memcpy(buf, "0123456789", sizeof(buf));
+ ASSERT_EXIT(printf("%d", strlen(buf)), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_Clang_DeathTest, strchr_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[10];
+ memcpy(buf, "0123456789", sizeof(buf));
+ ASSERT_EXIT(printf("%s", strchr(buf, 'a')), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_Clang_DeathTest, strrchr_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[10];
+ memcpy(buf, "0123456789", sizeof(buf));
+ ASSERT_EXIT(printf("%s", strrchr(buf, 'a')), testing::KilledBySignal(SIGABRT), "");
+}
+#endif
+
+TEST(Fortify2_Clang_DeathTest, strncat_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[10];
+ size_t n = atoi("10"); // avoid compiler optimizations
+ strncpy(buf, "012345678", n);
+ ASSERT_EXIT(strncat(buf, "9", n), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_Clang_DeathTest, strncat2_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[10];
+ buf[0] = '\0';
+ size_t n = atoi("10"); // avoid compiler optimizations
+ ASSERT_EXIT(strncat(buf, "0123456789", n), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_Clang_DeathTest, strcat_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char src[11];
+ strcpy(src, "0123456789");
+ char buf[10];
+ buf[0] = '\0';
+ ASSERT_EXIT(strcat(buf, src), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_Clang_DeathTest, memmove_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char buf[20];
+ strcpy(buf, "0123456789");
+ size_t n = atoi("10");
+ ASSERT_EXIT(memmove(buf + 11, buf, n), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_Clang_DeathTest, memcpy_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char bufa[10];
+ char bufb[10];
+ strcpy(bufa, "012345678");
+ size_t n = atoi("11");
+ ASSERT_EXIT(memcpy(bufb, bufa, n), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_Clang_DeathTest, strncpy_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ char bufa[15];
+ char bufb[10];
+ strcpy(bufa, "01234567890123");
+ size_t n = strlen(bufa);
+ ASSERT_EXIT(strncpy(bufb, bufa, n), testing::KilledBySignal(SIGABRT), "");
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t test_fortify2_inline(char* buf) {
+ return __bos(buf);
+}
+
+TEST(Fortify2_Clang, fortify_inline) {
+ char buf[1024];
+ ASSERT_EQ(test_fortify2_inline(buf), sizeof(buf));
+}