lkml.org 
[lkml]   [2008]   [Sep]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch] Add basic sanity checks to the syscall execution patch
Add basic sanity checks to the syscall execution patch

Several pieces of malware (rootkits etc) have the nasty habbit
of putting their own pointers into the syscall table.
For example, the recently "hot in the news" phalanx rootkit does this.

The patch below, while obviously not perfect protection against malware,
adds some cheap sanity checks to the syscall path to verify the
system call is actually still in the kernel code region and not some
external-to-this region such as a rootkit.

The overhead is very minimal; measured at 2 cycles or less.
(this is because the branches get predicted right and the rest of the
code is almost perfectly parallelizable... and an indirect function call
is a branch issue anyway)

with eyes-on-the-code help from Peter
the idea is from Ben Herrenschmidt

Signed-off-by: Arjan van de Ven

diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 109792b..f25c0a1 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -347,7 +347,12 @@ sysenter_past_esp:
sysenter_do_call:
cmpl $(nr_syscalls), %eax
jae syscall_badsys
- call *sys_call_table(,%eax,4)
+ mov sys_call_table(,%eax,4), %eax
+ cmp $_stext, %eax
+ jb syscall_badsys
+ cmp $_etext, %eax
+ jae syscall_badsys
+ call *%eax
movl %eax,PT_EAX(%esp)
LOCKDEP_SYS_EXIT
DISABLE_INTERRUPTS(CLBR_ANY)
@@ -426,7 +431,12 @@ ENTRY(system_call)
cmpl $(nr_syscalls), %eax
jae syscall_badsys
syscall_call:
- call *sys_call_table(,%eax,4)
+ mov sys_call_table(,%eax,4), %eax
+ cmp $_stext, %eax
+ jb syscall_badsys
+ cmp $_etext, %eax
+ jae syscall_badsys
+ call *%eax
movl %eax,PT_EAX(%esp) # store the return value
syscall_exit:
LOCKDEP_SYS_EXIT
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 89434d4..be42486 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -360,8 +360,13 @@ ENTRY(system_call_after_swapgs)
system_call_fastpath:
cmpq $__NR_syscall_max,%rax
ja badsys
+ mov sys_call_table(,%rax,8), %rax
+ cmpq $_stext, %rax
+ jb badsys
+ cmpq $_etext, %rax
+ jae badsys
movq %r10,%rcx
- call *sys_call_table(,%rax,8) # XXX: rip relative
+ call *%rax # XXX: rip relative
movq %rax,RAX-ARGOFFSET(%rsp)
/*
* Syscall return path ending with SYSRET (fast path)

\
 
 \ /
  Last update: 2008-09-04 04:53    [W:0.147 / U:0.224 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site