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 <flavio.ceolin@intel.com>
This commit is contained in:
parent
38a2e2cf89
commit
8ed4b62dc0
2 changed files with 17 additions and 2 deletions
|
@ -9,6 +9,8 @@
|
|||
#define ZEPHYR_ARCH_ARM_CORE_AARCH32_CORTEX_M_MPU_ARM_MPU_V7_INTERNAL_H_
|
||||
|
||||
|
||||
#include <sys/math_extras.h>
|
||||
|
||||
#define LOG_LEVEL CONFIG_MPU_LOG_LEVEL
|
||||
#include <logging/log.h>
|
||||
|
||||
|
@ -200,6 +202,7 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
|
|||
u32_t r_addr_start;
|
||||
u32_t r_size_lshift;
|
||||
u32_t r_addr_end;
|
||||
u32_t end;
|
||||
|
||||
/* Lock IRQs to ensure RNR value is correct when reading RBAR, RASR. */
|
||||
unsigned int key;
|
||||
|
@ -216,7 +219,12 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
|
|||
MPU_RASR_SIZE_Pos) + 1;
|
||||
r_addr_end = r_addr_start + (1UL << r_size_lshift) - 1;
|
||||
|
||||
if (start >= r_addr_start && (start + size - 1) <= r_addr_end) {
|
||||
size = size == 0 ? 0 : size - 1;
|
||||
if (u32_add_overflow(start, size, &end)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((start >= r_addr_start) && (end <= r_addr_end)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <soc.h>
|
||||
#include "arm_core_mpu_dev.h"
|
||||
#include <sys/__assert.h>
|
||||
#include <sys/math_extras.h>
|
||||
#include <linker/linker-defs.h>
|
||||
|
||||
#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)
|
|||
{
|
||||
u32_t r_addr_start;
|
||||
u32_t r_addr_end;
|
||||
u32_t end;
|
||||
|
||||
r_addr_start = SYSMPU->WORD[r_index][0];
|
||||
r_addr_end = SYSMPU->WORD[r_index][1];
|
||||
|
||||
if (start >= r_addr_start && (start + size - 1) <= r_addr_end) {
|
||||
size = size == 0 ? 0 : size - 1;
|
||||
if (u32_add_overflow(start, size, &end)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((start >= r_addr_start) && (end <= r_addr_end)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue