diff options
-rw-r--r-- | src/libc.c | 63 |
1 files changed, 63 insertions, 0 deletions
@@ -273,6 +273,69 @@ bionic___stack_chk_fail(void) abort(); } +size_t +bionic___strlen_chk(const char *s, size_t s_len) +{ + const size_t ret = strlen(s); + if (__builtin_expect(ret >= s_len, 0)) { + fprintf(stderr, "*** strlen read overflow detected ***\n"); + abort(); + } + return ret; +} + +size_t +bionic___fwrite_chk(const void * __restrict buf, size_t size, size_t count, FILE * __restrict stream, size_t buf_size) +{ + size_t total; + if (__builtin_expect(__builtin_mul_overflow(size, count, &total), 0)) { + // overflow: trigger the error path in fwrite + return fwrite(buf, size, count, stream); + } + + if (__builtin_expect(total > buf_size, 0)) { + fprintf(stderr, "*** fwrite read overflow detected ***\n"); + abort(); + } + + return fwrite(buf, size, count, stream); +} + +char* +bionic___strchr_chk(const char* p, int ch, size_t s_len) +{ + for (;; ++p, s_len--) { + if (__builtin_expect(s_len == 0, 0)) { + fprintf(stderr, "*** strchr buffer overrun detected ***\n"); + abort(); + } + + if (*p == ch) + return (char*)p; + else if (!*p) + return NULL; + } + assert(0 && "should not happen"); +} + +char* +bionic___strrchr_chk(const char* p, int ch, size_t s_len) +{ + const char *save; + for (save = NULL;; ++p, s_len--) { + if (__builtin_expect(s_len == 0, 0)) { + fprintf(stderr, "*** strchr buffer overrun detected ***\n"); + abort(); + } + + if (*p == ch) + save = p; + else if (!*p) + return (char*)save; + } + assert(0 && "should not happen"); +} + static inline int bionic_sysconf_to_glibc_sysconf(int name) { |