Improved safety for user memory accesses.
* Changed IS_USER_ADDRESS to check an address using USER_BASE and USER_SIZE, rather than just !IS_KERNEL_ADDRESS. The old check would allow user buffers to point into the physical memory map area. * Added an unmapped hole at the end of the bottom half of the address space which catches buffers that cross into the uncanonical address region. This also removes the need to check for uncanonical return addresses in the syscall handler, it is no longer possible for the return address to be uncanonical under normal circumstances. All cases in which the return address might be changed by the kernel are still handled via the IRET path.
This commit is contained in:
parent
b77772725c
commit
d93ed09564
@ -23,10 +23,10 @@
|
||||
#define USER_BASE 0x100000
|
||||
#define USER_BASE_ANY USER_BASE
|
||||
#define USER_SIZE (0x80000000 - (0x10000 + 0x100000))
|
||||
#define USER_TOP (USER_BASE + USER_SIZE)
|
||||
#define USER_TOP (USER_BASE + (USER_SIZE - 1))
|
||||
|
||||
#define KERNEL_USER_DATA_BASE 0x6fff0000
|
||||
#define USER_STACK_REGION 0x70000000
|
||||
#define USER_STACK_REGION_SIZE (USER_TOP - USER_STACK_REGION)
|
||||
#define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1)
|
||||
|
||||
#endif /* _KERNEL_ARCH_ARM_KERNEL_H */
|
||||
|
@ -23,10 +23,10 @@
|
||||
#define USER_BASE 0x100000
|
||||
#define USER_BASE_ANY USER_BASE
|
||||
#define USER_SIZE (0x80000000 - (0x10000 + 0x100000))
|
||||
#define USER_TOP (USER_BASE + USER_SIZE)
|
||||
#define USER_TOP (USER_BASE + (USER_SIZE - 1))
|
||||
|
||||
#define KERNEL_USER_DATA_BASE 0x6fff0000
|
||||
#define USER_STACK_REGION 0x70000000
|
||||
#define USER_STACK_REGION_SIZE (USER_TOP - USER_STACK_REGION)
|
||||
#define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1)
|
||||
|
||||
#endif /* _KERNEL_ARCH_M68K_KERNEL_H */
|
||||
|
@ -26,11 +26,11 @@
|
||||
#define USER_BASE 0x100000
|
||||
#define USER_BASE_ANY USER_BASE
|
||||
#define USER_SIZE (0x80000000 - (0x10000 + 0x100000))
|
||||
#define USER_TOP (USER_BASE + USER_SIZE)
|
||||
#define USER_TOP (USER_BASE + (USER_SIZE - 1))
|
||||
|
||||
#define KERNEL_USER_DATA_BASE 0x6fff0000
|
||||
#define USER_STACK_REGION 0x70000000
|
||||
#define USER_STACK_REGION_SIZE (USER_TOP - USER_STACK_REGION)
|
||||
#define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1)
|
||||
|
||||
#endif /* _KERNEL_ARCH_MIPSEL_KERNEL_H */
|
||||
|
||||
|
@ -23,10 +23,10 @@
|
||||
#define USER_BASE 0x100000
|
||||
#define USER_BASE_ANY USER_BASE
|
||||
#define USER_SIZE (0x80000000 - (0x10000 + 0x100000))
|
||||
#define USER_TOP (USER_BASE + USER_SIZE)
|
||||
#define USER_TOP (USER_BASE + (USER_SIZE - 1))
|
||||
|
||||
#define KERNEL_USER_DATA_BASE 0x6fff0000
|
||||
#define USER_STACK_REGION 0x70000000
|
||||
#define USER_STACK_REGION_SIZE (USER_TOP - USER_STACK_REGION)
|
||||
#define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1)
|
||||
|
||||
#endif /* _KERNEL_ARCH_PPC_KERNEL_H */
|
||||
|
@ -40,14 +40,17 @@
|
||||
#define KERNEL_PMAP_SIZE 0x8000000000
|
||||
|
||||
// Userspace address space layout.
|
||||
// There is a 2MB hole just before the end of the bottom half of the address
|
||||
// space. This means that if userland passes in a buffer that crosses into the
|
||||
// uncanonical address region, it will be caught through a page fault.
|
||||
#define USER_BASE 0x0
|
||||
#define USER_BASE_ANY 0x100000
|
||||
#define USER_SIZE 0x800000000000
|
||||
#define USER_TOP (USER_BASE + USER_SIZE)
|
||||
#define USER_SIZE (0x800000000000 - 0x200000)
|
||||
#define USER_TOP (USER_BASE + (USER_SIZE - 1))
|
||||
|
||||
#define KERNEL_USER_DATA_BASE 0x7fffefff0000
|
||||
#define USER_STACK_REGION 0x7ffff0000000
|
||||
#define USER_STACK_REGION_SIZE (USER_TOP - USER_STACK_REGION)
|
||||
#define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1)
|
||||
|
||||
|
||||
#else // __x86_64__
|
||||
@ -68,14 +71,14 @@
|
||||
* TODO: introduce the 1Mb lower barrier again - it's only used for vm86 mode,
|
||||
* and this should be moved into the kernel (and address space) completely.
|
||||
*/
|
||||
#define USER_BASE 0x00
|
||||
#define USER_BASE 0x0
|
||||
#define USER_BASE_ANY 0x100000
|
||||
#define USER_SIZE (KERNEL_BASE - 0x10000)
|
||||
#define USER_TOP (USER_BASE + USER_SIZE)
|
||||
#define USER_TOP (USER_BASE + (USER_SIZE - 1))
|
||||
|
||||
#define KERNEL_USER_DATA_BASE 0x6fff0000
|
||||
#define USER_STACK_REGION 0x70000000
|
||||
#define USER_STACK_REGION_SIZE (USER_TOP - USER_STACK_REGION)
|
||||
#define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1)
|
||||
|
||||
|
||||
#endif // __x86_64__
|
||||
|
@ -31,7 +31,14 @@
|
||||
#endif
|
||||
|
||||
// Buffers passed in from user-space shouldn't point into the kernel.
|
||||
#define IS_USER_ADDRESS(x) (!IS_KERNEL_ADDRESS(x))
|
||||
#if USER_BASE == 0
|
||||
# define IS_USER_ADDRESS(x) ((addr_t)(x) <= USER_TOP)
|
||||
#elif USER_TOP == __HAIKU_ADDR_MAX
|
||||
# define IS_USER_ADDRESS(x) ((addr_t)(x) >= USER_BASE)
|
||||
#else
|
||||
# define IS_USER_ADDRESS(x) \
|
||||
((addr_t)(x) >= USER_BASE && (addr_t)(x) <= USER_TOP)
|
||||
#endif
|
||||
|
||||
#define DEBUG_KERNEL_STACKS
|
||||
// Note, debugging kernel stacks doesn't really work yet. Since the
|
||||
|
@ -393,19 +393,6 @@ FUNCTION(x86_64_syscall_entry):
|
||||
cmpq $SYSCALL_RESTORE_SIGNAL_FRAME, %r14
|
||||
je .Liret
|
||||
|
||||
// If the return address is not canonical, return using the IRET path.
|
||||
// On Intel's implementation of SYSRET, the canonical address check for the
|
||||
// return address is performed before the switch to user mode, so a fault
|
||||
// for a non-canonical address will be triggered in kernel mode. However, by
|
||||
// then we will have switched onto the user stack meaning the kernel could
|
||||
// be tricked into executing with the user RSP. Using IRET will handle
|
||||
// non-canonical addresses properly.
|
||||
movq IFRAME_user_sp(%rsp), %rax
|
||||
sarq $47, %rax
|
||||
incl %eax
|
||||
cmpl $1, %eax
|
||||
ja .Liret
|
||||
|
||||
// Restore the iframe and RCX/R11 for SYSRET.
|
||||
RESTORE_IFRAME()
|
||||
pop %rcx
|
||||
|
Loading…
Reference in New Issue
Block a user