Add strncat and strrchr to bounds checking
This commit is contained in:
parent
f48efeef8c
commit
28fa4d3db6
6 changed files with 89 additions and 7 deletions
|
@ -269,7 +269,9 @@
|
||||||
__BOTH(int, strcmp, (const char*, const char*))
|
__BOTH(int, strcmp, (const char*, const char*))
|
||||||
__BOTH(int, strncmp, (const char*, const char*, __SIZE_TYPE__))
|
__BOTH(int, strncmp, (const char*, const char*, __SIZE_TYPE__))
|
||||||
__BOTH(char*, strcat, (char*, const char*))
|
__BOTH(char*, strcat, (char*, const char*))
|
||||||
|
__BOTH(char*, strncat, (char*, const char*, __SIZE_TYPE__))
|
||||||
__BOTH(char*, strchr, (const char*, int))
|
__BOTH(char*, strchr, (const char*, int))
|
||||||
|
__BOTH(char*, strrchr, (const char*, int))
|
||||||
__BOTH(char*, strdup, (const char*))
|
__BOTH(char*, strdup, (const char*))
|
||||||
#if defined __ARM_EABI__
|
#if defined __ARM_EABI__
|
||||||
__BOUND(void*,__aeabi_memcpy,(void*,const void*,__SIZE_TYPE__))
|
__BOUND(void*,__aeabi_memcpy,(void*,const void*,__SIZE_TYPE__))
|
||||||
|
|
42
lib/bcheck.c
42
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_strcmp(const char *s1, const char *s2);
|
||||||
DLL_EXPORT int __bound_strncmp(const char *s1, const char *s2, size_t n);
|
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_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_strchr(const char *string, int ch);
|
||||||
|
DLL_EXPORT char *__bound_strrchr(const char *string, int ch);
|
||||||
DLL_EXPORT char *__bound_strdup(const char *s);
|
DLL_EXPORT char *__bound_strdup(const char *s);
|
||||||
|
|
||||||
#if defined(__arm__) && defined(__ARM_EABI__)
|
#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_strcmp_count;
|
||||||
static unsigned long long bound_strncmp_count;
|
static unsigned long long bound_strncmp_count;
|
||||||
static unsigned long long bound_strcat_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_strchr_count;
|
||||||
|
static unsigned long long bound_strrchr_count;
|
||||||
static unsigned long long bound_strdup_count;
|
static unsigned long long bound_strdup_count;
|
||||||
static unsigned long long bound_not_found;
|
static unsigned long long bound_not_found;
|
||||||
#define INCR_COUNT(x) ++x
|
#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_strcmp_count %llu\n", bound_strcmp_count);
|
||||||
fprintf (stderr, "bound_strncmp_count %llu\n", bound_strncmp_count);
|
fprintf (stderr, "bound_strncmp_count %llu\n", bound_strncmp_count);
|
||||||
fprintf (stderr, "bound_strcat_count %llu\n", bound_strcat_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_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_strdup_count %llu\n", bound_strdup_count);
|
||||||
fprintf (stderr, "bound_not_found %llu\n", bound_not_found);
|
fprintf (stderr, "bound_not_found %llu\n", bound_not_found);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1940,6 +1946,24 @@ char *__bound_strcat(char *dest, const char *src)
|
||||||
return strcat(r, s);
|
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)
|
char *__bound_strchr(const char *s, int c)
|
||||||
{
|
{
|
||||||
const unsigned char *str = (const unsigned char *) s;
|
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;
|
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)
|
char *__bound_strdup(const char *s)
|
||||||
{
|
{
|
||||||
const char *p = s;
|
const char *p = s;
|
||||||
|
|
|
@ -156,8 +156,18 @@ int main()
|
||||||
#elif defined test_bcheck_125
|
#elif defined test_bcheck_125
|
||||||
strcat(&a[3], &a[0]);
|
strcat(&a[3], &a[0]);
|
||||||
#elif defined test_bcheck_126
|
#elif defined test_bcheck_126
|
||||||
strchr(&b[0], 'a');
|
strncat(&a[7], &a[0], 3);
|
||||||
#elif defined test_bcheck_127
|
#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]));
|
free(strdup(&b[0]));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,9 +134,29 @@
|
||||||
[returns 255]
|
[returns 255]
|
||||||
|
|
||||||
[test_bcheck_126]
|
[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]
|
[returns 255]
|
||||||
|
|
||||||
[test_bcheck_127]
|
[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]
|
[returns 255]
|
||||||
|
|
|
@ -60,12 +60,20 @@ main (void)
|
||||||
r = (__builtin_memcmp (p, str, sizeof(str)));
|
r = (__builtin_memcmp (p, str, sizeof(str)));
|
||||||
printf(" 11:%d", !r);
|
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);
|
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);
|
p = __builtin_strdup (str);
|
||||||
r = (__builtin_memcmp (p, str, sizeof(str)));
|
r = (__builtin_memcmp (p, str, sizeof(str)));
|
||||||
printf(" 13:%d", !r);
|
printf(" 15:%d", !r);
|
||||||
__builtin_free(p);
|
__builtin_free(p);
|
||||||
|
|
||||||
p = __builtin_malloc (100);
|
p = __builtin_malloc (100);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
BOUNDS OFF:
|
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:
|
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
|
||||||
|
|
Loading…
Reference in a new issue