From e93effb6fb1e8290099970317890f05c7dc650af Mon Sep 17 00:00:00 2001 From: ganlan Date: Thu, 11 Aug 2022 17:29:16 +0800 Subject: [PATCH] expansion frotify functions Signed-off-by: ganlan --- libc-test/src/functionalext/fortify/string.c | 84 ++++++++++++++++++++ porting/linux/user/include/fortify/string.h | 19 +++++ porting/linux/user/src/fortify/fortify.c | 12 ++- 3 files changed, 112 insertions(+), 3 deletions(-) diff --git a/libc-test/src/functionalext/fortify/string.c b/libc-test/src/functionalext/fortify/string.c index efeb415b..b6b55c25 100644 --- a/libc-test/src/functionalext/fortify/string.c +++ b/libc-test/src/functionalext/fortify/string.c @@ -91,6 +91,58 @@ static void test_strcat_0020() return; } +/** + * @tc.name : test_strcat_0010 + * @tc.desc : After adding fortify, test the normal strcat of the function. + * @tc.level : Level 0 + */ +static void test_strncat_0010() +{ + char src[SIZE_15]; + strcpy(src, STRLEN_10); + char dst[SIZE_20]; + memset(dst, 0, SIZE_20); + strncat(dst, src, strlen(src)); + TEST(dst[0] == EQ_0); +} + +/** + * @tc.name : test_strcat_0020 + * @tc.desc : Ability to test the strcat Fortify runtime + * @tc.level : Level 2 + */ +static void test_strncat_0020() +{ + struct sigaction sigabrt = { + .sa_handler = SignalHandler, + }; + sigaction(SIGABRT, &sigabrt, NULL); + + char src[SIZE_15]; + strcpy(src, STRLEN_10); + char dst[SIZE_5]; + memset(dst, 0, SIZE_5); + int status; + int pid = fork(); + switch (pid) { + case -1: + t_error("fork failed: %s\n", strerror(errno)); + break; + case 0: + strncat(dst, src, strlen(src)); + exit(0); + default: + waitpid(pid, &status, WUNTRACED); + TEST(WIFEXITED(status) == 0); + TEST(WIFSTOPPED(status) == 1); + TEST(WSTOPSIG(status) == SIGSTOP); + kill(pid, SIGCONT); + break; + } + return; +} + + /** * @tc.name : test_stpcpy_0010 * @tc.desc : After adding fortify, test the normal stpcpy of the function. @@ -798,9 +850,40 @@ static void test_memset_0020() return; } +static void test_strlen_0010() +{ + struct sigaction sigabrt = { + .sa_handler = SignalHandler, + }; + sigaction(SIGABRT, &sigabrt, NULL); + + char buf[SIZE_10]; + memcpy(buf, STRLEN_10, sizeof(buf)); + int status; + int pid = fork(); + switch (pid) { + case -1: + t_error("fork failed: %s\n", strerror(errno)); + break; + case 0: + strlen(buf); + exit(0); + default: + waitpid(pid, &status, WUNTRACED); + TEST(WIFEXITED(status) == 0); + TEST(WIFSTOPPED(status) == 1); + TEST(WSTOPSIG(status) == SIGSTOP); + kill(pid, SIGCONT); + break; + } + return; +} + int main(int argc, char *argv[]) { test_strcat_0010(); test_strcat_0020(); + test_strncat_0010(); + test_strncat_0020(); test_strchr_0010(); test_strchr_0020(); test_strncpy_0010(); @@ -821,6 +904,7 @@ int main(int argc, char *argv[]) { test_memset_0020(); test_memcpy_0010(); test_memcpy_0020(); + test_strlen_0010(); #ifdef _GNU_SOURCE test_mempcpy_0010(); diff --git a/porting/linux/user/include/fortify/string.h b/porting/linux/user/include/fortify/string.h index 40f25c28..a11a95b1 100644 --- a/porting/linux/user/include/fortify/string.h +++ b/porting/linux/user/include/fortify/string.h @@ -29,6 +29,7 @@ size_t __strlcpy_diagnose(char*, const char*, size_t, size_t); size_t __strlcat_diagnose(char*, const char*, size_t, size_t); char *__strchr_diagnose(const char* p, int ch, size_t s_len); char *__strrchr_diagnose(const char *p, int ch, size_t s_len); +size_t __strlen_chk(const char* s, size_t s_len); #ifdef __FORTIFY_COMPILATION __DIAGNOSE_FORTIFY_INLINE @@ -94,6 +95,15 @@ __DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LE(__DIAGNOSE_BOS(dst), __builtin_str #endif } +#ifdef __FORTIFY_RUNTIME +__DIAGNOSE_FORTIFY_INLINE +char *strncat(char* const dst __DIAGNOSE_PASS_OBJECT_SIZE, const char* src, size_t n) +__DIAGNOSE_OVERLOAD +{ + return __builtin___strncat_chk(dst, src, n, __DIAGNOSE_BOS(dst)); +} +#endif + #ifdef __FORTIFY_RUNTIME __DIAGNOSE_FORTIFY_INLINE char *stpncpy(char *const dst __DIAGNOSE_PASS_OBJECT_SIZE, @@ -221,6 +231,15 @@ __DIAGNOSE_OVERLOAD return __builtin_strrchr(s, c); } +#ifdef __FORTIFY_RUNTIME +__DIAGNOSE_FORTIFY_INLINE +size_t strlen(const char* const s __DIAGNOSE_PASS_OBJECT_SIZE0) +__DIAGNOSE_OVERLOAD +{ + return __strlen_chk(s, __DIAGNOSE_BOS0(s)); +} +#endif + #endif // __FORTIFY_COMPILATION #ifdef __cplusplus } diff --git a/porting/linux/user/src/fortify/fortify.c b/porting/linux/user/src/fortify/fortify.c index e0bbacf3..12121715 100644 --- a/porting/linux/user/src/fortify/fortify.c +++ b/porting/linux/user/src/fortify/fortify.c @@ -167,18 +167,24 @@ static inline void __diagnose_count(const char *fn, const char *identifier, size size_t __strlen_chk(const char* s, size_t s_len) { - size_t ret = strlen(s); + size_t ret = __DIAGNOSE_CALL_BYPASSING_FORTIFY(strlen)(s); if (__DIAGNOSE_PREDICT_FALSE(ret >= s_len)) { __fortify_error("strlen: detected read past end of buffer\n"); - return 0; } return ret; } +char* __strncat_chk(char* dst, const char* src, size_t len, size_t dst_buf_size) +{ + size_t src_len = strlen(src) + strlen(dst); + __diagnose_buffer_access("strncat", "write into", src_len, dst_buf_size); + return __DIAGNOSE_CALL_BYPASSING_FORTIFY(strncat)(dst, src, len); +} + char* __strcat_chk(char* dst, const char* src, size_t dst_buf_size) { size_t src_len = strlen(src) + strlen(dst); - __diagnose_buffer_access("strcpy", "write into", src_len, dst_buf_size); + __diagnose_buffer_access("strcat", "write into", src_len, dst_buf_size); return __DIAGNOSE_CALL_BYPASSING_FORTIFY(strcat)(dst, src); } -- GitLab