Skip to content

Commit e33f8d3

Browse files
thgarnieKAGA-KOKO
authored andcommitted
arm/syscalls: Optimize address limit check
Disable the generic address limit check in favor of an architecture specific optimized implementation. The generic implementation using pending work flags did not work well with ARM and alignment faults. The address limit is checked on each syscall return path to user-mode path as well as the irq user-mode return function. If the address limit was changed, a function is called to report data corruption (stopping the kernel or process based on configuration). The address limit check has to be done before any pending work because they can reset the address limit and the process is killed using a SIGKILL signal. For example the lkdtm address limit check does not work because the signal to kill the process will reset the user-mode address limit. Signed-off-by: Thomas Garnier <[email protected]> Signed-off-by: Kees Cook <[email protected]> Tested-by: Kees Cook <[email protected]> Tested-by: Leonard Crestez <[email protected]> Reviewed-by: Kees Cook <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Cc: Pratyush Anand <[email protected]> Cc: Dave Martin <[email protected]> Cc: Will Drewry <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Will Deacon <[email protected]> Cc: Russell King <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: David Howells <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Al Viro <[email protected]> Cc: [email protected] Cc: Yonghong Song <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected]
1 parent 2404269 commit e33f8d3

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

arch/arm/kernel/entry-common.S

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <asm/unistd.h>
1313
#include <asm/ftrace.h>
1414
#include <asm/unwind.h>
15+
#include <asm/memory.h>
1516
#ifdef CONFIG_AEABI
1617
#include <asm/unistd-oabi.h>
1718
#endif
@@ -48,10 +49,14 @@ ret_fast_syscall:
4849
UNWIND(.fnstart )
4950
UNWIND(.cantunwind )
5051
disable_irq_notrace @ disable interrupts
52+
ldr r2, [tsk, #TI_ADDR_LIMIT]
53+
cmp r2, #TASK_SIZE
54+
blne addr_limit_check_failed
5155
ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
5256
tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
5357
bne fast_work_pending
5458

59+
5560
/* perform architecture specific actions before user return */
5661
arch_ret_to_user r1, lr
5762

@@ -74,6 +79,9 @@ ret_fast_syscall:
7479
UNWIND(.cantunwind )
7580
str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
7681
disable_irq_notrace @ disable interrupts
82+
ldr r2, [tsk, #TI_ADDR_LIMIT]
83+
cmp r2, #TASK_SIZE
84+
blne addr_limit_check_failed
7785
ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
7886
tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
7987
beq no_work_pending
@@ -106,6 +114,9 @@ ENTRY(ret_to_user)
106114
ret_slow_syscall:
107115
disable_irq_notrace @ disable interrupts
108116
ENTRY(ret_to_user_from_irq)
117+
ldr r2, [tsk, #TI_ADDR_LIMIT]
118+
cmp r2, #TASK_SIZE
119+
blne addr_limit_check_failed
109120
ldr r1, [tsk, #TI_FLAGS]
110121
tst r1, #_TIF_WORK_MASK
111122
bne slow_work_pending

arch/arm/kernel/signal.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/uaccess.h>
1515
#include <linux/tracehook.h>
1616
#include <linux/uprobes.h>
17+
#include <linux/syscalls.h>
1718

1819
#include <asm/elf.h>
1920
#include <asm/cacheflush.h>
@@ -673,3 +674,9 @@ struct page *get_signal_page(void)
673674

674675
return page;
675676
}
677+
678+
/* Defer to generic check */
679+
asmlinkage void addr_limit_check_failed(void)
680+
{
681+
addr_limit_user_check();
682+
}

0 commit comments

Comments
 (0)