From c8708d9bf30bae2ccb2eab3d6c274107ddc36259 Mon Sep 17 00:00:00 2001 From: Jakob Olesen Date: Tue, 7 May 2019 10:17:35 -0700 Subject: [PATCH] misc: Replace uses of __builtin_*_overflow() with . Use the new math_extras functions instead of calling builtins directly. Change a few local variables to size_t after checking that all uses of the variable actually expects a size_t. Signed-off-by: Jakob Olesen --- include/toolchain/xcc.h | 12 ------------ kernel/include/syscall_handler.h | 7 ++++--- kernel/mempool.c | 6 +++--- kernel/msg_q.c | 4 ++-- kernel/poll.c | 11 +++++------ kernel/thread.c | 6 +++--- kernel/userspace.c | 13 +++++++------ lib/libc/minimal/source/stdlib/malloc.c | 17 +++-------------- subsys/net/lib/sockets/sockets.c | 6 +++--- 9 files changed, 30 insertions(+), 52 deletions(-) diff --git a/include/toolchain/xcc.h b/include/toolchain/xcc.h index cdf317c08fa..c93abb2bd71 100644 --- a/include/toolchain/xcc.h +++ b/include/toolchain/xcc.h @@ -40,16 +40,4 @@ #define __builtin_unreachable() do { __ASSERT(false, "Unreachable code"); } \ while (true) -/* TODO: XCC doesn't define the below macros which are useful for checking - * overflows. This needs to be fixed. - */ -#define __builtin_add_overflow(a, b, output) \ - ({ *output = (a) + (b); false; }) -#define __builtin_mul_overflow(a, b, output) \ - ({ *output = (a) * (b); false; }) -#define __builtin_umul_overflow(a, b, output) \ - ({ *output = (a) * (b); false; }) -#define __builtin_umulll_overflow(a, b, output) \ - ({ *output = (a) * (b); false; }) - #endif diff --git a/kernel/include/syscall_handler.h b/kernel/include/syscall_handler.h index 5ce456470cf..ab2449dbbc9 100644 --- a/kernel/include/syscall_handler.h +++ b/kernel/include/syscall_handler.h @@ -13,6 +13,7 @@ #ifndef _ASMLANGUAGE #include #include +#include #include #include @@ -353,9 +354,9 @@ extern int z_user_string_copy(char *dst, const char *src, size_t maxlen); #define Z_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, write) \ ({ \ u32_t product; \ - Z_SYSCALL_VERIFY_MSG(!__builtin_umul_overflow((u32_t)(nmemb), \ - (u32_t)(size), \ - &product), \ + Z_SYSCALL_VERIFY_MSG(!u32_mul_overflow((u32_t)(nmemb), \ + (u32_t)(size), \ + &product), \ "%ux%u array is too large", \ (u32_t)(nmemb), (u32_t)(size)) || \ Z_SYSCALL_MEMORY(ptr, product, write); \ diff --git a/kernel/mempool.c b/kernel/mempool.c index a611e4bfbf7..f124447ae34 100644 --- a/kernel/mempool.c +++ b/kernel/mempool.c @@ -10,6 +10,7 @@ #include #include #include +#include #include /* Linker-defined symbols bound the static pool structs */ @@ -144,8 +145,7 @@ void *k_mem_pool_malloc(struct k_mem_pool *pool, size_t size) * get a block large enough to hold an initial (hidden) block * descriptor, as well as the space the caller requested */ - if (__builtin_add_overflow(size, sizeof(struct k_mem_block_id), - &size)) { + if (size_add_overflow(size, sizeof(struct k_mem_block_id), &size)) { return NULL; } if (k_mem_pool_alloc(pool, &block, size, K_NO_WAIT) != 0) { @@ -193,7 +193,7 @@ void *k_calloc(size_t nmemb, size_t size) void *ret; size_t bounds; - if (__builtin_mul_overflow(nmemb, size, &bounds)) { + if (size_mul_overflow(nmemb, size, &bounds)) { return NULL; } diff --git a/kernel/msg_q.c b/kernel/msg_q.c index b796e74db9b..1ab3fdc8529 100644 --- a/kernel/msg_q.c +++ b/kernel/msg_q.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -73,8 +74,7 @@ int z_impl_k_msgq_alloc_init(struct k_msgq *q, size_t msg_size, int ret; size_t total_size; - if (__builtin_umul_overflow((unsigned int)msg_size, max_msgs, - (unsigned int *)&total_size)) { + if (size_mul_overflow(msg_size, max_msgs, &total_size)) { ret = -EINVAL; } else { buffer = z_thread_malloc(total_size); diff --git a/kernel/poll.c b/kernel/poll.c index 682ee79593a..2c7cb8afa70 100644 --- a/kernel/poll.c +++ b/kernel/poll.c @@ -264,7 +264,7 @@ Z_SYSCALL_HANDLER(k_poll, events, num_events, timeout) int ret; k_spinlock_key_t key; struct k_poll_event *events_copy = NULL; - unsigned int bounds; + u32_t bounds; /* Validate the events buffer and make a copy of it in an * allocated kernel-side buffer. @@ -273,11 +273,10 @@ Z_SYSCALL_HANDLER(k_poll, events, num_events, timeout) ret = -EINVAL; goto out; } - if (Z_SYSCALL_VERIFY_MSG( - !__builtin_umul_overflow(num_events, - sizeof(struct k_poll_event), - &bounds), - "num_events too large")) { + if (Z_SYSCALL_VERIFY_MSG(!u32_mul_overflow(num_events, + sizeof(struct k_poll_event), + &bounds), + "num_events too large")) { ret = -EINVAL; goto out; } diff --git a/kernel/thread.c b/kernel/thread.c index 8bfce822ce2..03ac8f19289 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -475,9 +476,8 @@ Z_SYSCALL_HANDLER(k_thread_create, /* Verify that the stack size passed in is OK by computing the total * size and comparing it with the size value in the object metadata */ - Z_OOPS(Z_SYSCALL_VERIFY_MSG(!__builtin_uadd_overflow(K_THREAD_STACK_RESERVED, - stack_size, - &total_size), + Z_OOPS(Z_SYSCALL_VERIFY_MSG(!u32_add_overflow(K_THREAD_STACK_RESERVED, + stack_size, &total_size), "stack size overflow (%u+%u)", stack_size, K_THREAD_STACK_RESERVED)); diff --git a/kernel/userspace.c b/kernel/userspace.c index 40aa8fbf910..a1595445b2e 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -672,7 +673,7 @@ int z_user_to_copy(void *dst, const void *src, size_t size) char *z_user_string_alloc_copy(const char *src, size_t maxlen) { - unsigned long actual_len; + size_t actual_len; int err; char *ret = NULL; @@ -682,10 +683,10 @@ char *z_user_string_alloc_copy(const char *src, size_t maxlen) } if (actual_len == maxlen) { /* Not NULL terminated */ - printk("string too long %p (%lu)\n", src, actual_len); + printk("string too long %p (%zu)\n", src, actual_len); goto out; } - if (__builtin_uaddl_overflow(actual_len, 1, &actual_len)) { + if (size_add_overflow(actual_len, 1, &actual_len)) { printk("overflow\n"); goto out; } @@ -705,7 +706,7 @@ out: int z_user_string_copy(char *dst, const char *src, size_t maxlen) { - unsigned long actual_len; + size_t actual_len; int ret, err; actual_len = z_user_string_nlen(src, maxlen, &err); @@ -715,11 +716,11 @@ int z_user_string_copy(char *dst, const char *src, size_t maxlen) } if (actual_len == maxlen) { /* Not NULL terminated */ - printk("string too long %p (%lu)\n", src, actual_len); + printk("string too long %p (%zu)\n", src, actual_len); ret = EINVAL; goto out; } - if (__builtin_uaddl_overflow(actual_len, 1, &actual_len)) { + if (size_add_overflow(actual_len, 1, &actual_len)) { printk("overflow\n"); ret = EINVAL; goto out; diff --git a/lib/libc/minimal/source/stdlib/malloc.c b/lib/libc/minimal/source/stdlib/malloc.c index 2ec25b17c4b..ae8efbc6673 100644 --- a/lib/libc/minimal/source/stdlib/malloc.c +++ b/lib/libc/minimal/source/stdlib/malloc.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -66,23 +67,11 @@ void free(void *ptr) sys_mem_pool_free(ptr); } -static bool size_t_mul_overflow(size_t a, size_t b, size_t *res) -{ -#if __SIZEOF_SIZE_T__ == 4 - return __builtin_umul_overflow((unsigned int)a, (unsigned int)b, - (unsigned int *)res); -#else /* __SIZEOF_SIZE_T__ == 8 */ - return __builtin_umulll_overflow((unsigned long long)a, - (unsigned long long)b, - (unsigned long long *)res); -#endif -} - void *calloc(size_t nmemb, size_t size) { void *ret; - if (size_t_mul_overflow(nmemb, size, &size)) { + if (size_mul_overflow(nmemb, size, &size)) { errno = ENOMEM; return NULL; } @@ -144,7 +133,7 @@ void *realloc(void *ptr, size_t requested_size) void *reallocarray(void *ptr, size_t nmemb, size_t size) { - if (size_t_mul_overflow(nmemb, size, &size)) { + if (size_mul_overflow(nmemb, size, &size)) { errno = ENOMEM; return NULL; } diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index 5ce0b35ce90..2f1ce3e2858 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -17,6 +17,7 @@ LOG_MODULE_REGISTER(net_sock, CONFIG_NET_SOCKETS_LOG_LEVEL); #include #include #include +#include #include "sockets_internal.h" @@ -1037,12 +1038,11 @@ int z_impl_zsock_poll(struct zsock_pollfd *fds, int nfds, int timeout) Z_SYSCALL_HANDLER(zsock_poll, fds, nfds, timeout) { struct zsock_pollfd *fds_copy; - unsigned int fds_size; + size_t fds_size; int ret; /* Copy fds array from user mode */ - if (__builtin_umul_overflow(nfds, sizeof(struct zsock_pollfd), - &fds_size)) { + if (size_mul_overflow(nfds, sizeof(struct zsock_pollfd), &fds_size)) { errno = EFAULT; return -1; }