Merge "libc: add limited FORTIFY_SOURCE support for clang"
This commit is contained in:
commit
dd0880fec3
11 changed files with 571 additions and 17 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -144,6 +144,7 @@ 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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
298
tests/fortify1_test_clang.cpp
Normal file
298
tests/fortify1_test_clang.cpp
Normal file
|
@ -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));
|
||||
}
|
|
@ -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), "");
|
||||
}
|
||||
|
|
171
tests/fortify2_test_clang.cpp
Normal file
171
tests/fortify2_test_clang.cpp
Normal file
|
@ -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));
|
||||
}
|
Loading…
Reference in a new issue