Skip to content

Commit c892fd3

Browse files
author
Flavio Ceolin
committed
syscalls: arm: Fix possible overflow in is_in_region function
This function is widely used by functions that validate memory buffers. Macros used to check permissions, like Z_SYSCALL_MEMORY_READ and Z_SYSCALL_MEMORY_WRITE, use these functions to check that a pointers passed by user threads in a syscall. Signed-off-by: Flavio Ceolin <[email protected]>
1 parent de3c5ae commit c892fd3

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

arch/arm/core/aarch32/cortex_m/mpu/arm_mpu_v7_internal.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#define ZEPHYR_ARCH_ARM_CORE_AARCH32_CORTEX_M_MPU_ARM_MPU_V7_INTERNAL_H_
1010

1111

12+
#include <sys/math_extras.h>
13+
1214
#define LOG_LEVEL CONFIG_MPU_LOG_LEVEL
1315
#include <logging/log.h>
1416

@@ -200,6 +202,7 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
200202
u32_t r_addr_start;
201203
u32_t r_size_lshift;
202204
u32_t r_addr_end;
205+
u32_t end;
203206

204207
/* Lock IRQs to ensure RNR value is correct when reading RBAR, RASR. */
205208
unsigned int key;
@@ -216,7 +219,12 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
216219
MPU_RASR_SIZE_Pos) + 1;
217220
r_addr_end = r_addr_start + (1UL << r_size_lshift) - 1;
218221

219-
if (start >= r_addr_start && (start + size - 1) <= r_addr_end) {
222+
size = size == 0 ? 0 : size - 1;
223+
if (u32_add_overflow(start, size, &end)) {
224+
return 0;
225+
}
226+
227+
if ((start >= r_addr_start) && (end <= r_addr_end)) {
220228
return 1;
221229
}
222230

arch/arm/core/aarch32/cortex_m/mpu/nxp_mpu.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <soc.h>
1111
#include "arm_core_mpu_dev.h"
1212
#include <sys/__assert.h>
13+
#include <sys/math_extras.h>
1314
#include <linker/linker-defs.h>
1415

1516
#define LOG_LEVEL CONFIG_MPU_LOG_LEVEL
@@ -428,11 +429,17 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
428429
{
429430
u32_t r_addr_start;
430431
u32_t r_addr_end;
432+
u32_t end;
431433

432434
r_addr_start = SYSMPU->WORD[r_index][0];
433435
r_addr_end = SYSMPU->WORD[r_index][1];
434436

435-
if (start >= r_addr_start && (start + size - 1) <= r_addr_end) {
437+
size = size == 0 ? 0 : size - 1;
438+
if (u32_add_overflow(start, size, &end)) {
439+
return 0;
440+
}
441+
442+
if ((start >= r_addr_start) && (end <= r_addr_end)) {
436443
return 1;
437444
}
438445

0 commit comments

Comments
 (0)