On Tue, Mar 14, 2017 at 8:39 AM, Andy Lutomirski [off-list ref] wrote:
Even though my name isn't Ingo, Linus keeps trying to get me to be the
actual maintainer of this file. :) How about (sorry about whitespace
damage):
:D
#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
movq PER_CPU_VAR(current_task), %rax
bt $63, TASK_addr_limit(%rax)
jc syscall_return_slowpath
#endif
Now the kernel is totally unchanged if the config option is off and
it's fast and simple if the option is on.
I like using bt for fast comparison.
We want to enforce the address limit by default, not only when
CONFIG_BUG_ON_DATA_CORRUPTION is enabled. I tested this one:
/* Check user-mode state on fast path return. */
movq PER_CPU_VAR(current_task), %rax
btq $63, TASK_addr_limit(%rax)
jnc 1f
#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
call syscall_return_slowpath
jmp return_from_SYSCALL_64
#else
movq $TASK_SIZE_MAX, %rcx
movq %rcx, TASK_addr_limit(%rax)
#endif
1:
I saw that syscall_return_slowpath is supposed to be called not jumped
to. I could just call verify_pre_usermode_state that would be about
the same.
If we want to avoid if/def then I guess this one is the best I can think of:
/* Check user-mode state on fast path return. */
movq PER_CPU_VAR(current_task), %rax
btq $63, TASK_addr_limit(%rax)
jnc 1f
call verify_pre_usermode_state
1:
The check is fast and the call will happen only on corruption.
What do you think?
--
Thomas