From: Dmitry Kovalenko Date: Sat, 11 Jul 2015 18:39:10 +0000 (+0300) Subject: [IMPROVE] Add interface for syscalls patching X-Git-Tag: submit/tizen/20151123.110932~35 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F22%2F43622%2F3;p=kernel%2Fswap-modules.git [IMPROVE] Add interface for syscalls patching Change-Id: I95035afda4f70432b3e192f2ee6730ae2bc90efe Signed-off-by: Dmitry Kovalenko --- diff --git a/uprobe/Kbuild b/uprobe/Kbuild index beb9b6a..11be1b1 100644 --- a/uprobe/Kbuild +++ b/uprobe/Kbuild @@ -10,4 +10,5 @@ swap_uprobe-$(CONFIG_ARM) += arch/arm/swap-asm/swap_uprobes.o \ ### X86 -swap_uprobe-$(CONFIG_X86) += arch/x86/swap-asm/swap_uprobes.o +swap_uprobe-$(CONFIG_X86) += arch/x86/swap-asm/swap_uprobes.o \ + arch/x86/swap-asm/swap_sc_patch.o diff --git a/uprobe/arch/x86/swap-asm/swap_sc_patch.c b/uprobe/arch/x86/swap-asm/swap_sc_patch.c new file mode 100644 index 0000000..01b4ea7 --- /dev/null +++ b/uprobe/arch/x86/swap-asm/swap_sc_patch.c @@ -0,0 +1,88 @@ +/** + * swap_sc_patch.c + * @author Dmitry Kovalenko + * @section LICENSE + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * @section COPYRIGHT + * + * Copyright (C) Samsung Electronics, 2015 + * + * @section DESCRIPTION + * + * Patching of sys_call_table + */ + +#include +#include "swap_sc_patch.h" + +static unsigned long original_syscall; +static int patched_syscall = -1; + +/* disable write protection */ +#define swap_disable_wprot() \ + asm("pushl %eax \n" \ + "movl %cr0, %eax \n" \ + "andl $0xfffeffff, %eax \n" \ + "movl %eax, %cr0 \n" \ + "popl %eax"); + +/* enable write protection */ +#define swap_enable_wprot() \ + asm("push %eax \n" \ + "movl %cr0, %eax \n" \ + "orl $0x00010000, %eax \n" \ + "movl %eax, %cr0 \n" \ + "popl %eax"); + +void patch_syscall(int syscall_n, unsigned long new_syscall_addr) +{ + unsigned long tmp; + unsigned long *sc_table; + + /* + * Search for sys_call_table (4 bytes before sysenter_after_call) + * sysenter_do_call function which locates before sysenter_after_call + * has sys_call_table address in call instruction (latest instruction) + */ + tmp = swap_ksyms("sysenter_after_call"); + sc_table = *(unsigned long **)(tmp - 4); + + swap_disable_wprot(); + original_syscall = sc_table[syscall_n]; + sc_table[syscall_n] = new_syscall_addr; + patched_syscall = syscall_n; + swap_enable_wprot(); +} + +void swap_depatch_syscall(void) +{ + patch_syscall(patched_syscall, original_syscall); + patched_syscall = -1; +} + +asmlinkage long sys_swap_func(void) +{ + /* Your code here */ + + return -ENOSYS; +} + +#define NI_SYSCALL4SWAP 31 +void swap_patch_syscall(void) +{ + patch_syscall(NI_SYSCALL4SWAP, (unsigned long)&sys_swap_func); +} diff --git a/uprobe/arch/x86/swap-asm/swap_sc_patch.h b/uprobe/arch/x86/swap-asm/swap_sc_patch.h new file mode 100644 index 0000000..9b42fac --- /dev/null +++ b/uprobe/arch/x86/swap-asm/swap_sc_patch.h @@ -0,0 +1,2 @@ +void swap_depatch_syscall(void); +void swap_patch_syscall(void);