From 26a18ab863ecb3be87f963233d250814f428bb6f Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Mon, 19 Nov 2018 11:35:32 +0200 Subject: libc: support various _chk functions --- src/libc.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/libc.c b/src/libc.c index e3dfa96..96057b7 100644 --- a/src/libc.c +++ b/src/libc.c @@ -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) { -- cgit v1.2.3