提交 bc56b7b3 编写于 作者: Z Zou Cao 提交者: Shile Zhang

alinux: Hookers: add arm64 support

arm64 has't global write protect set, here we remove the write
proctect in pmd table and update the hook data.
Signed-off-by: NZou Cao <zoucao@linux.alibaba.com>
Acked-by: NXunlei Pang <xlpang@linux.alibaba.com>
上级 64259ab4
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
#include <net/inet_common.h> #include <net/inet_common.h>
#include <net/ipv6.h> #include <net/ipv6.h>
#include <linux/inet.h> #include <linux/inet.h>
#include <linux/kallsyms.h>
#include <linux/hugetlb.h>
#include <asm/tlbflush.h>
#include <linux/hookers.h> #include <linux/hookers.h>
...@@ -28,6 +31,10 @@ struct hooked_place { ...@@ -28,6 +31,10 @@ struct hooked_place {
struct list_head chain; /* hookers chain */ struct list_head chain; /* hookers chain */
}; };
#ifdef CONFIG_ARM64
static struct mm_struct *orig_init_mm;
#endif
static spinlock_t hookers_lock; static spinlock_t hookers_lock;
static struct sock * static struct sock *
...@@ -253,6 +260,7 @@ void hooker_uninstall(struct hooker *h) ...@@ -253,6 +260,7 @@ void hooker_uninstall(struct hooker *h)
} }
EXPORT_SYMBOL_GPL(hooker_uninstall); EXPORT_SYMBOL_GPL(hooker_uninstall);
#ifdef CONFIG_X86
static inline unsigned int hookers_clear_cr0(void) static inline unsigned int hookers_clear_cr0(void)
{ {
unsigned int cr0 = read_cr0(); unsigned int cr0 = read_cr0();
...@@ -265,6 +273,52 @@ static inline void hookers_restore_cr0(unsigned int val) ...@@ -265,6 +273,52 @@ static inline void hookers_restore_cr0(unsigned int val)
{ {
write_cr0(val); write_cr0(val);
} }
#else
static void remove_memprotect(unsigned long addr)
{
pgd_t *pgd, pgdd;
pud_t *pud, pudd;
pmd_t *pmd, pmdd;
u64 addr_aligned;
addr_aligned = addr & PAGE_MASK;
pgd = pgd_offset(orig_init_mm, (unsigned long)addr_aligned);
pgdd = READ_ONCE(*pgd);
pud = pud_offset(pgd, (unsigned long)addr_aligned);
pudd = READ_ONCE(*pud);
pmd = pmd_offset(pud, (unsigned long)addr_aligned);
pmdd = READ_ONCE(*pmd);
set_pmd(pmd, __pmd(pmd_val(pmdd) & ~PMD_SECT_RDONLY));
flush_tlb_kernel_range(addr_aligned, addr_aligned + PAGE_SIZE);
}
static void set_memprotect(unsigned long addr)
{
pgd_t *pgd, pgdd;
pud_t *pud, pudd;
pmd_t *pmd, pmdd;
u64 addr_aligned;
addr_aligned = addr & PAGE_MASK;
pgd = pgd_offset(orig_init_mm, (unsigned long)addr_aligned);
pgdd = READ_ONCE(*pgd);
pud = pud_offset(pgd, (unsigned long)addr_aligned);
pudd = READ_ONCE(*pud);
pmd = pmd_offset(pud, (unsigned long)addr_aligned);
pmdd = READ_ONCE(*pmd);
set_pmd(pmd, __pmd(pmd_val(pmdd) | PMD_SECT_RDONLY));
flush_tlb_kernel_range(addr_aligned, addr_aligned + PAGE_SIZE);
}
#endif
static void *hookers_seq_start(struct seq_file *seq, loff_t *pos) static void *hookers_seq_start(struct seq_file *seq, loff_t *pos)
{ {
...@@ -321,20 +375,36 @@ static int hookers_init(void) ...@@ -321,20 +375,36 @@ static int hookers_init(void)
if (!proc_create("hookers", 0444, NULL, &hookers_seq_fops)) if (!proc_create("hookers", 0444, NULL, &hookers_seq_fops))
return -ENODEV; return -ENODEV;
#ifdef CONFIG_ARM64
orig_init_mm = (struct mm_struct *)kallsyms_lookup_name("init_mm");
if (!orig_init_mm)
return -ENODEV;
#endif
spin_lock_init(&hookers_lock); spin_lock_init(&hookers_lock);
for (i = 0; i < PLACE_TABLE_SZ; i++) { for (i = 0; i < PLACE_TABLE_SZ; i++) {
#ifdef CONFIG_X86
unsigned int cr0; unsigned int cr0;
#endif
void **place = place_table[i].place; void **place = place_table[i].place;
place_table[i].orig = *place; place_table[i].orig = *place;
if (!place_table[i].stub) if (!place_table[i].stub)
break; break;
INIT_LIST_HEAD(&place_table[i].chain); INIT_LIST_HEAD(&place_table[i].chain);
#ifdef CONFIG_X86
get_online_cpus(); get_online_cpus();
cr0 = hookers_clear_cr0(); cr0 = hookers_clear_cr0();
*place = place_table[i].stub; *place = place_table[i].stub;
hookers_restore_cr0(cr0); hookers_restore_cr0(cr0);
put_online_cpus(); put_online_cpus();
#else
get_online_cpus();
remove_memprotect((unsigned long)place);
*place = place_table[i].stub;
set_memprotect((unsigned long)place);
put_online_cpus();
#endif
} }
return 0; return 0;
...@@ -347,14 +417,22 @@ static void hookers_exit(void) ...@@ -347,14 +417,22 @@ static void hookers_exit(void)
remove_proc_entry("hookers", NULL); remove_proc_entry("hookers", NULL);
for (i = 0; i < PLACE_TABLE_SZ; i++) { for (i = 0; i < PLACE_TABLE_SZ; i++) {
unsigned int cr0;
void **place = place_table[i].place; void **place = place_table[i].place;
#ifdef CONFIG_X86
unsigned int cr0;
get_online_cpus(); get_online_cpus();
cr0 = hookers_clear_cr0(); cr0 = hookers_clear_cr0();
*place = place_table[i].orig; *place = place_table[i].orig;
hookers_restore_cr0(cr0); hookers_restore_cr0(cr0);
put_online_cpus(); put_online_cpus();
#else
get_online_cpus();
remove_memprotect((unsigned long)place);
*place = place_table[i].orig;
set_memprotect((unsigned long)place);
put_online_cpus();
#endif
} }
synchronize_rcu(); synchronize_rcu();
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册