diff options
-rw-r--r-- | libc/include/fcntl.h | 4 | ||||
-rw-r--r-- | libc/include/stdio.h | 4 | ||||
-rw-r--r-- | libc/include/string.h | 22 | ||||
-rw-r--r-- | libc/include/strings.h | 4 | ||||
-rw-r--r-- | libc/include/sys/cdefs.h | 5 | ||||
-rw-r--r-- | libc/include/sys/stat.h | 4 | ||||
-rw-r--r-- | tests/Android.mk | 24 | ||||
-rw-r--r-- | tests/fortify1_test.cpp | 26 | ||||
-rw-r--r-- | tests/fortify1_test_clang.cpp | 298 | ||||
-rw-r--r-- | tests/fortify2_test.cpp | 26 | ||||
-rw-r--r-- | tests/fortify2_test_clang.cpp | 171 |
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)); +} |