summaryrefslogtreecommitdiff
path: root/src/libc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libc.c')
-rw-r--r--src/libc.c63
1 files changed, 63 insertions, 0 deletions
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)
{