kernel: Add option to ensure writable pages are not executable
This adds CONFIG_EXECUTE_XOR_WRITE, which is enabled by default on systems that support controlling whether a page can contain executable code. This is also known as W^X[1]. Trying to add a memory domain with a page that is both executable and writable, either for supervisor mode threads, or for user mode threads, will result in a kernel panic. There are few cases where a writable page should also be executable (JIT compilers, which are most likely out of scope for Zephyr), so an option is provided to disable the check. Since the memory domain APIs are executed in supervisor mode, a determined person could bypass these checks with ease. This is seen more as a way to avoid people shooting themselves in the foot. [1] https://en.wikipedia.org/wiki/W%5EX Signed-off-by: Leandro Pereira <leandro.pereira@intel.com>
This commit is contained in:
parent
36adf4e432
commit
b007b64d30
5 changed files with 82 additions and 1 deletions
|
@ -216,6 +216,24 @@ extern "C" {
|
|||
#define K_MEM_PARTITION_P_RWX_U_RWX (P_RW_U_RW)
|
||||
#define K_MEM_PARTITION_P_RWX_U_RX (P_RW_U_RO)
|
||||
#define K_MEM_PARTITION_P_RX_U_RX (P_RO_U_RO)
|
||||
|
||||
#define K_MEM_PARTITION_IS_WRITABLE(attr) \
|
||||
({ \
|
||||
int __is_writable__; \
|
||||
switch (attr) { \
|
||||
case P_RW_U_RW: \
|
||||
case P_RW_U_RO: \
|
||||
case P_RW_U_NA: \
|
||||
__is_writable__ = 1; \
|
||||
break; \
|
||||
default: \
|
||||
__is_writable__ = 0; \
|
||||
} \
|
||||
__is_writable__; \
|
||||
})
|
||||
#define K_MEM_PARTITION_IS_EXECUTABLE(attr) \
|
||||
(!((attr) & (NOT_EXEC)))
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \
|
||||
BUILD_ASSERT_MSG(!(((size) & ((size) - 1))) && (size) >= 32 && \
|
||||
|
@ -243,6 +261,34 @@ extern "C" {
|
|||
MPU_REGION_SU_RWX)
|
||||
#define K_MEM_PARTITION_P_RX_U_RX (MPU_REGION_READ | MPU_REGION_EXEC | \
|
||||
MPU_REGION_SU)
|
||||
|
||||
#define K_MEM_PARTITION_IS_WRITABLE(attr) \
|
||||
({ \
|
||||
int __is_writable__; \
|
||||
switch (attr) { \
|
||||
case MPU_REGION_WRITE: \
|
||||
case MPU_REGION_SU_RW: \
|
||||
__is_writable__ = 1; \
|
||||
break; \
|
||||
default: \
|
||||
__is_writable__ = 0; \
|
||||
} \
|
||||
__is_writable__; \
|
||||
})
|
||||
#define K_MEM_PARTITION_IS_EXECUTABLE(attr) \
|
||||
({ \
|
||||
int __is_executable__; \
|
||||
switch (attr) { \
|
||||
case MPU_REGION_SU_RX: \
|
||||
case MPU_REGION_EXEC: \
|
||||
__is_executable__ = 1; \
|
||||
break; \
|
||||
default: \
|
||||
__is_executable__ = 0; \
|
||||
} \
|
||||
__is_executable__; \
|
||||
})
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \
|
||||
BUILD_ASSERT_MSG((size) % 32 == 0 && (size) >= 32 && \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue