diff --git a/include/tccdefs.h b/include/tccdefs.h index c32df1b6..7d9017d5 100644 --- a/include/tccdefs.h +++ b/include/tccdefs.h @@ -269,7 +269,9 @@ __BOTH(int, strcmp, (const char*, const char*)) __BOTH(int, strncmp, (const char*, const char*, __SIZE_TYPE__)) __BOTH(char*, strcat, (char*, const char*)) + __BOTH(char*, strncat, (char*, const char*, __SIZE_TYPE__)) __BOTH(char*, strchr, (const char*, int)) + __BOTH(char*, strrchr, (const char*, int)) __BOTH(char*, strdup, (const char*)) #if defined __ARM_EABI__ __BOUND(void*,__aeabi_memcpy,(void*,const void*,__SIZE_TYPE__)) diff --git a/lib/bcheck.c b/lib/bcheck.c index 9216d0f7..0f225869 100644 --- a/lib/bcheck.c +++ b/lib/bcheck.c @@ -292,7 +292,9 @@ DLL_EXPORT char *__bound_strncpy(char *dst, const char *src, size_t n); DLL_EXPORT int __bound_strcmp(const char *s1, const char *s2); DLL_EXPORT int __bound_strncmp(const char *s1, const char *s2, size_t n); DLL_EXPORT char *__bound_strcat(char *dest, const char *src); +DLL_EXPORT char *__bound_strncat(char *dest, const char *src, size_t n); DLL_EXPORT char *__bound_strchr(const char *string, int ch); +DLL_EXPORT char *__bound_strrchr(const char *string, int ch); DLL_EXPORT char *__bound_strdup(const char *s); #if defined(__arm__) && defined(__ARM_EABI__) @@ -424,7 +426,9 @@ static unsigned long long bound_strncpy_count; static unsigned long long bound_strcmp_count; static unsigned long long bound_strncmp_count; static unsigned long long bound_strcat_count; +static unsigned long long bound_strncat_count; static unsigned long long bound_strchr_count; +static unsigned long long bound_strrchr_count; static unsigned long long bound_strdup_count; static unsigned long long bound_not_found; #define INCR_COUNT(x) ++x @@ -1259,7 +1263,9 @@ void __attribute__((destructor)) __bound_exit(void) fprintf (stderr, "bound_strcmp_count %llu\n", bound_strcmp_count); fprintf (stderr, "bound_strncmp_count %llu\n", bound_strncmp_count); fprintf (stderr, "bound_strcat_count %llu\n", bound_strcat_count); + fprintf (stderr, "bound_strncat_count %llu\n", bound_strncat_count); fprintf (stderr, "bound_strchr_count %llu\n", bound_strchr_count); + fprintf (stderr, "bound_strrchr_count %llu\n", bound_strrchr_count); fprintf (stderr, "bound_strdup_count %llu\n", bound_strdup_count); fprintf (stderr, "bound_not_found %llu\n", bound_not_found); #endif @@ -1940,6 +1946,24 @@ char *__bound_strcat(char *dest, const char *src) return strcat(r, s); } +char *__bound_strncat(char *dest, const char *src, size_t n) +{ + char *r = dest; + const char *s = src; + size_t len = n; + + dprintf(stderr, "%s, %s(): %p, %p, 0x%lx\n", + __FILE__, __FUNCTION__, dest, src, (unsigned long)n); + INCR_COUNT(bound_strncat_count); + while (*dest++); + while (len-- && *src++); + __bound_check(r, (dest - r) + (src - s) - 1, "strncat dest"); + __bound_check(s, src - s, "strncat src"); + if (check_overlap(r, (dest - r) + (src - s) - 1, s, src - s, "strncat")) + return dest; + return strncat(r, s, n); +} + char *__bound_strchr(const char *s, int c) { const unsigned char *str = (const unsigned char *) s; @@ -1957,6 +1981,24 @@ char *__bound_strchr(const char *s, int c) return *str == ch ? (char *) str : NULL; } +char *__bound_strrchr(const char *s, int c) +{ + const unsigned char *str = (const unsigned char *) s; + unsigned char ch = c; + + dprintf(stderr, "%s, %s(): %p, %d\n", + __FILE__, __FUNCTION__, s, ch); + INCR_COUNT(bound_strrchr_count); + while (*str++); + __bound_check(s, (const char *)str - s, "strrchr"); + while (str != (const unsigned char *)s) { + if (*--str == ch) + break; + } + __bound_check(s, (const char *)str - s, "strrchr"); + return *str == ch ? (char *) str : NULL; +} + char *__bound_strdup(const char *s) { const char *p = s; diff --git a/tests/tests2/112_backtrace.c b/tests/tests2/112_backtrace.c index 8489bd32..0b596d08 100644 --- a/tests/tests2/112_backtrace.c +++ b/tests/tests2/112_backtrace.c @@ -156,8 +156,18 @@ int main() #elif defined test_bcheck_125 strcat(&a[3], &a[0]); #elif defined test_bcheck_126 - strchr(&b[0], 'a'); + strncat(&a[7], &a[0], 3); #elif defined test_bcheck_127 + strncat(&a[0], &b[3], 8); +#elif defined test_bcheck_128 + strncat(&a[0], &a[4], 3); +#elif defined test_bcheck_129 + strncat(&a[3], &a[0], 10); +#elif defined test_bcheck_130 + strchr(&b[0], 'a'); +#elif defined test_bcheck_131 + strrchr(&b[0], 'a'); +#elif defined test_bcheck_132 free(strdup(&b[0])); #endif } diff --git a/tests/tests2/112_backtrace.expect b/tests/tests2/112_backtrace.expect index 68986c6e..ec2c6b8e 100644 --- a/tests/tests2/112_backtrace.expect +++ b/tests/tests2/112_backtrace.expect @@ -134,9 +134,29 @@ [returns 255] [test_bcheck_126] -112_backtrace.c:159: at main: BCHECK: invalid pointer ........, size 0x? in strchr +112_backtrace.c:159: at main: BCHECK: invalid pointer ........, size 0x? in strncat dest [returns 255] [test_bcheck_127] -112_backtrace.c:161: at main: BCHECK: invalid pointer ........, size 0x? in strdup +112_backtrace.c:161: at main: BCHECK: invalid pointer ........, size 0x? in strncat dest +[returns 255] + +[test_bcheck_128] +112_backtrace.c:163: at main: BCHECK: overlapping regions ........(0x?), ........(0x?) in strncat +[returns 255] + +[test_bcheck_129] +112_backtrace.c:165: at main: BCHECK: overlapping regions ........(0x?), ........(0x?) in strncat +[returns 255] + +[test_bcheck_130] +112_backtrace.c:167: at main: BCHECK: invalid pointer ........, size 0x? in strchr +[returns 255] + +[test_bcheck_131] +112_backtrace.c:169: at main: BCHECK: invalid pointer ........, size 0x? in strrchr +[returns 255] + +[test_bcheck_132] +112_backtrace.c:171: at main: BCHECK: invalid pointer ........, size 0x? in strdup [returns 255] diff --git a/tests/tests2/117_builtins.c b/tests/tests2/117_builtins.c index 4da28ff5..4c6ffd4b 100644 --- a/tests/tests2/117_builtins.c +++ b/tests/tests2/117_builtins.c @@ -60,12 +60,20 @@ main (void) r = (__builtin_memcmp (p, str, sizeof(str))); printf(" 11:%d", !r); - r = (__builtin_strchr(p, 'z') != &p[25]); + tmp[0] = '\0'; + p = __builtin_strncat(tmp, str, __builtin_strlen(str)); + r = (__builtin_memcmp (p, str, sizeof(str))); printf(" 12:%d", !r); + r = (__builtin_strchr(p, 'z') != &p[25]); + printf(" 13:%d", !r); + + r = (__builtin_strrchr(p, 'z') != &p[25]); + printf(" 14:%d", !r); + p = __builtin_strdup (str); r = (__builtin_memcmp (p, str, sizeof(str))); - printf(" 13:%d", !r); + printf(" 15:%d", !r); __builtin_free(p); p = __builtin_malloc (100); diff --git a/tests/tests2/117_builtins.expect b/tests/tests2/117_builtins.expect index 776e4329..f2c78ba7 100644 --- a/tests/tests2/117_builtins.expect +++ b/tests/tests2/117_builtins.expect @@ -1,4 +1,4 @@ BOUNDS OFF: - 1:1 2:1 3:1 4:1 5:1 6:1 7:1 8:1 9:1 10:1 11:1 12:1 13:1 + 1:1 2:1 3:1 4:1 5:1 6:1 7:1 8:1 9:1 10:1 11:1 12:1 13:1 14:1 15:1 BOUNDS ON: - 1:1 2:1 3:1 4:1 5:1 6:1 7:1 8:1 9:1 10:1 11:1 12:1 13:1 + 1:1 2:1 3:1 4:1 5:1 6:1 7:1 8:1 9:1 10:1 11:1 12:1 13:1 14:1 15:1