From bb98202fa613ba5f441f96d9cdc303b5595f6cb3 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Wed, 8 Jan 2025 14:53:56 +0100 Subject: [PATCH] zephyr: fix overflow and overlap checks in memcpy_s This patch addresses an issue in the `memcpy_s` function within the Zephyr RTOS string header. The issue was identified during IPC3 fuzz testing with UndefinedBehaviorSanitizer enabled. Changes include: - Adding `stdint.h` for `uintptr_t` type. - Adding checks to prevent overflow in pointer arithmetic. - Adjusting overlap checks to avoid overflow. These changes ensure that the `memcpy_s` function correctly handles edge cases, preventing undefined behavior due to pointer arithmetic overflow and memory overlap. Fixes #9768 Signed-off-by: Tomasz Leman --- zephyr/include/rtos/string.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/zephyr/include/rtos/string.h b/zephyr/include/rtos/string.h index 8f7a657f3caf..49c26acd17da 100644 --- a/zephyr/include/rtos/string.h +++ b/zephyr/include/rtos/string.h @@ -8,6 +8,7 @@ /* Zephyr uses a C library so lets use it */ #include +#include #include #include @@ -40,11 +41,19 @@ static inline int memcpy_s(void *dest, size_t dest_size, if (!dest || !src) return -EINVAL; - if ((dest >= src && (char *)dest < ((char *)src + count)) || - (src >= dest && (char *)src < ((char *)dest + dest_size))) + if (count > dest_size) return -EINVAL; - if (count > dest_size) + uintptr_t dest_addr = (uintptr_t)dest; + uintptr_t src_addr = (uintptr_t)src; + + /* Check for overflow in pointer arithmetic */ + if ((dest_addr + dest_size < dest_addr) || (src_addr + count < src_addr)) + return -EINVAL; + + /* Check for overlap without causing overflow */ + if ((dest_addr >= src_addr && dest_addr < src_addr + count) || + (src_addr >= dest_addr && src_addr < dest_addr + dest_size)) return -EINVAL; memcpy(dest, src, count);