Unified · Split
| @@ -269,7 +269,9 @@ · 268 unmodified lines | ||
| 269 | 269 | __BOTH(int, strcmp, (const char*, const char*)) |
| 270 | 270 | __BOTH(int, strncmp, (const char*, const char*, __SIZE_TYPE__)) |
| 271 | 271 | __BOTH(char*, strcat, (char*, const char*)) |
| 272 | + __BOTH(char*, strncat, (char*, const char*, __SIZE_TYPE__)) | |
| 272 | 273 | __BOTH(char*, strchr, (const char*, int)) |
| 274 | + __BOTH(char*, strrchr, (const char*, int)) | |
| 273 | 275 | __BOTH(char*, strdup, (const char*)) |
| 274 | 276 | #if defined __ARM_EABI__ |
| 275 | 277 | __BOUND(void*,__aeabi_memcpy,(void*,const void*,__SIZE_TYPE__)) |
| @@ -292,7 +292,9 @@ DLL_EXPORT char *__bound_strncpy(char *dst, const char *src, size_t n); · 291 unmodified lines | ||
| 292 | 292 | DLL_EXPORT int __bound_strcmp(const char *s1, const char *s2); |
| 293 | 293 | DLL_EXPORT int __bound_strncmp(const char *s1, const char *s2, size_t n); |
| 294 | 294 | DLL_EXPORT char *__bound_strcat(char *dest, const char *src); |
| 295 | +DLL_EXPORT char *__bound_strncat(char *dest, const char *src, size_t n); | |
| 295 | 296 | DLL_EXPORT char *__bound_strchr(const char *string, int ch); |
| 297 | +DLL_EXPORT char *__bound_strrchr(const char *string, int ch); | |
| 296 | 298 | DLL_EXPORT char *__bound_strdup(const char *s); |
| 297 | 299 | |
| 298 | 300 | #if defined(__arm__) && defined(__ARM_EABI__) |
| @@ -424,7 +426,9 @@ static unsigned long long bound_strncpy_count; · 125 unmodified lines | ||
| 424 | 426 | static unsigned long long bound_strcmp_count; |
| 425 | 427 | static unsigned long long bound_strncmp_count; |
| 426 | 428 | static unsigned long long bound_strcat_count; |
| 429 | +static unsigned long long bound_strncat_count; | |
| 427 | 430 | static unsigned long long bound_strchr_count; |
| 431 | +static unsigned long long bound_strrchr_count; | |
| 428 | 432 | static unsigned long long bound_strdup_count; |
| 429 | 433 | static unsigned long long bound_not_found; |
| 430 | 434 | #define INCR_COUNT(x) ++x |
| @@ -1259,7 +1263,9 @@ void __attribute__((destructor)) __bound_exit(void) · 828 unmodified lines | ||
| 1259 | 1263 | fprintf (stderr, "bound_strcmp_count %llu\n", bound_strcmp_count); |
| 1260 | 1264 | fprintf (stderr, "bound_strncmp_count %llu\n", bound_strncmp_count); |
| 1261 | 1265 | fprintf (stderr, "bound_strcat_count %llu\n", bound_strcat_count); |
| 1266 | + fprintf (stderr, "bound_strncat_count %llu\n", bound_strncat_count); | |
| 1262 | 1267 | fprintf (stderr, "bound_strchr_count %llu\n", bound_strchr_count); |
| 1268 | + fprintf (stderr, "bound_strrchr_count %llu\n", bound_strrchr_count); | |
| 1263 | 1269 | fprintf (stderr, "bound_strdup_count %llu\n", bound_strdup_count); |
| 1264 | 1270 | fprintf (stderr, "bound_not_found %llu\n", bound_not_found); |
| 1265 | 1271 | #endif |
| @@ -1940,6 +1946,24 @@ char *__bound_strcat(char *dest, const char *src) · 674 unmodified lines | ||
| 1940 | 1946 | return strcat(r, s); |
| 1941 | 1947 | } |
| 1942 | 1948 | |
| 1949 | +char *__bound_strncat(char *dest, const char *src, size_t n) | |
| 1950 | +{ | |
| 1951 | + char *r = dest; | |
| 1952 | + const char *s = src; | |
| 1953 | + size_t len = n; | |
| 1954 | + | |
| 1955 | + dprintf(stderr, "%s, %s(): %p, %p, 0x%lx\n", | |
| 1956 | + __FILE__, __FUNCTION__, dest, src, (unsigned long)n); | |
| 1957 | + INCR_COUNT(bound_strncat_count); | |
| 1958 | + while (*dest++); | |
| 1959 | + while (len-- && *src++); | |
| 1960 | + __bound_check(r, (dest - r) + (src - s) - 1, "strncat dest"); | |
| 1961 | + __bound_check(s, src - s, "strncat src"); | |
| 1962 | + if (check_overlap(r, (dest - r) + (src - s) - 1, s, src - s, "strncat")) | |
| 1963 | + return dest; | |
| 1964 | + return strncat(r, s, n); | |
| 1965 | +} | |
| 1966 | + | |
| 1943 | 1967 | char *__bound_strchr(const char *s, int c) |
| 1944 | 1968 | { |
| 1945 | 1969 | const unsigned char *str = (const unsigned char *) s; |
| @@ -1957,6 +1981,24 @@ char *__bound_strchr(const char *s, int c) · 11 unmodified lines | ||
| 1957 | 1981 | return *str == ch ? (char *) str : NULL; |
| 1958 | 1982 | } |
| 1959 | 1983 | |
| 1984 | +char *__bound_strrchr(const char *s, int c) | |
| 1985 | +{ | |
| 1986 | + const unsigned char *str = (const unsigned char *) s; | |
| 1987 | + unsigned char ch = c; | |
| 1988 | + | |
| 1989 | + dprintf(stderr, "%s, %s(): %p, %d\n", | |
| 1990 | + __FILE__, __FUNCTION__, s, ch); | |
| 1991 | + INCR_COUNT(bound_strrchr_count); | |
| 1992 | + while (*str++); | |
| 1993 | + __bound_check(s, (const char *)str - s, "strrchr"); | |
| 1994 | + while (str != (const unsigned char *)s) { | |
| 1995 | + if (*--str == ch) | |
| 1996 | + break; | |
| 1997 | + } | |
| 1998 | + __bound_check(s, (const char *)str - s, "strrchr"); | |
| 1999 | + return *str == ch ? (char *) str : NULL; | |
| 2000 | +} | |
| 2001 | + | |
| 1960 | 2002 | char *__bound_strdup(const char *s) |
| 1961 | 2003 | { |
| 1962 | 2004 | const char *p = s; |
| @@ -156,8 +156,18 @@ int main() · 155 unmodified lines | ||
| 156 | 156 | #elif defined test_bcheck_125 |
| 157 | 157 | strcat(&a[3], &a[0]); |
| 158 | 158 | #elif defined test_bcheck_126 |
| 159 | − strchr(&b[0], 'a'); | |
| 159 | + strncat(&a[7], &a[0], 3); | |
| 160 | 160 | #elif defined test_bcheck_127 |
| 161 | + strncat(&a[0], &b[3], 8); | |
| 162 | +#elif defined test_bcheck_128 | |
| 163 | + strncat(&a[0], &a[4], 3); | |
| 164 | +#elif defined test_bcheck_129 | |
| 165 | + strncat(&a[3], &a[0], 10); | |
| 166 | +#elif defined test_bcheck_130 | |
| 167 | + strchr(&b[0], 'a'); | |
| 168 | +#elif defined test_bcheck_131 | |
| 169 | + strrchr(&b[0], 'a'); | |
| 170 | +#elif defined test_bcheck_132 | |
| 161 | 171 | free(strdup(&b[0])); |
| 162 | 172 | #endif |
| 163 | 173 | } |
| @@ -134,9 +134,29 @@ · 133 unmodified lines | ||
| 134 | 134 | [returns 255] |
| 135 | 135 | |
| 136 | 136 | [test_bcheck_126] |
| 137 | −112_backtrace.c:159: at main: BCHECK: invalid pointer ........, size 0x? in strchr | |
| 137 | +112_backtrace.c:159: at main: BCHECK: invalid pointer ........, size 0x? in strncat dest | |
| 138 | 138 | [returns 255] |
| 139 | 139 | |
| 140 | 140 | [test_bcheck_127] |
| 141 | −112_backtrace.c:161: at main: BCHECK: invalid pointer ........, size 0x? in strdup | |
| 141 | +112_backtrace.c:161: at main: BCHECK: invalid pointer ........, size 0x? in strncat dest | |
| 142 | +[returns 255] | |
| 143 | + | |
| 144 | +[test_bcheck_128] | |
| 145 | +112_backtrace.c:163: at main: BCHECK: overlapping regions ........(0x?), ........(0x?) in strncat | |
| 146 | +[returns 255] | |
| 147 | + | |
| 148 | +[test_bcheck_129] | |
| 149 | +112_backtrace.c:165: at main: BCHECK: overlapping regions ........(0x?), ........(0x?) in strncat | |
| 150 | +[returns 255] | |
| 151 | + | |
| 152 | +[test_bcheck_130] | |
| 153 | +112_backtrace.c:167: at main: BCHECK: invalid pointer ........, size 0x? in strchr | |
| 154 | +[returns 255] | |
| 155 | + | |
| 156 | +[test_bcheck_131] | |
| 157 | +112_backtrace.c:169: at main: BCHECK: invalid pointer ........, size 0x? in strrchr | |
| 158 | +[returns 255] | |
| 159 | + | |
| 160 | +[test_bcheck_132] | |
| 161 | +112_backtrace.c:171: at main: BCHECK: invalid pointer ........, size 0x? in strdup | |
| 142 | 162 | [returns 255] |
| @@ -60,12 +60,20 @@ main (void) · 59 unmodified lines | ||
| 60 | 60 | r = (__builtin_memcmp (p, str, sizeof(str))); |
| 61 | 61 | printf(" 11:%d", !r); |
| 62 | 62 | |
| 63 | − r = (__builtin_strchr(p, 'z') != &p[25]); | |
| 63 | + tmp[0] = '\0'; | |
| 64 | + p = __builtin_strncat(tmp, str, __builtin_strlen(str)); | |
| 65 | + r = (__builtin_memcmp (p, str, sizeof(str))); | |
| 64 | 66 | printf(" 12:%d", !r); |
| 65 | 67 | |
| 68 | + r = (__builtin_strchr(p, 'z') != &p[25]); | |
| 69 | + printf(" 13:%d", !r); | |
| 70 | + | |
| 71 | + r = (__builtin_strrchr(p, 'z') != &p[25]); | |
| 72 | + printf(" 14:%d", !r); | |
| 73 | + | |
| 66 | 74 | p = __builtin_strdup (str); |
| 67 | 75 | r = (__builtin_memcmp (p, str, sizeof(str))); |
| 68 | − printf(" 13:%d", !r); | |
| 76 | + printf(" 15:%d", !r); | |
| 69 | 77 | __builtin_free(p); |
| 70 | 78 | |
| 71 | 79 | p = __builtin_malloc (100); |
| @@ -1,4 +1,4 @@ | ||
| 1 | 1 | BOUNDS OFF: |
| 2 | − 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 | |
| 2 | + 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 | |
| 3 | 3 | BOUNDS ON: |
| 4 | − 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 | |
| 4 | + 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 | |