Skip to content

Commit

Permalink
zephyr: fix overflow and overlap checks in memcpy_s
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
tmleman committed Jan 8, 2025
1 parent 4094048 commit 7a32b9f
Showing 1 changed file with 12 additions and 3 deletions.
15 changes: 12 additions & 3 deletions zephyr/include/rtos/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

/* Zephyr uses a C library so lets use it */
#include <string.h>
#include <stdint.h>
#include <stddef.h>
#include <errno.h>

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 7a32b9f

Please sign in to comment.