Skip to content

Commit 91d2d7d

Browse files
Flavio Ceolinnashif
authored andcommitted
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 13fd2d3 commit 91d2d7d

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
200200
u32_t r_addr_start;
201201
u32_t r_size_lshift;
202202
u32_t r_addr_end;
203+
u32_t end;
203204

204205
/* Lock IRQs to ensure RNR value is correct when reading RBAR, RASR. */
205206
unsigned int key;
@@ -216,7 +217,12 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
216217
MPU_RASR_SIZE_Pos) + 1;
217218
r_addr_end = r_addr_start + (1UL << r_size_lshift) - 1;
218219

219-
if (start >= r_addr_start && (start + size - 1) <= r_addr_end) {
220+
size = size == 0 ? 0 : size - 1;
221+
if (__builtin_add_overflow(start, size, &end)) {
222+
return 0;
223+
}
224+
225+
if ((start >= r_addr_start) && (end <= r_addr_end)) {
220226
return 1;
221227
}
222228

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,11 +429,17 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
429429
{
430430
u32_t r_addr_start;
431431
u32_t r_addr_end;
432+
u32_t end;
432433

433434
r_addr_start = SYSMPU->WORD[r_index][0];
434435
r_addr_end = SYSMPU->WORD[r_index][1];
435436

436-
if (start >= r_addr_start && (start + size - 1) <= r_addr_end) {
437+
size = size == 0 ? 0 : size - 1;
438+
if (__builtin_add_overflow(start, size, &end)) {
439+
return 0;
440+
}
441+
442+
if ((start >= r_addr_start) && (end <= r_addr_end)) {
437443
return 1;
438444
}
439445

0 commit comments

Comments
 (0)