Skip to content

Commit

Permalink
kernel: add hookmanager
Browse files Browse the repository at this point in the history
  • Loading branch information
jouyouyun committed Dec 3, 2020
1 parent a4a6edf commit 29d7bed
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 23 deletions.
19 changes: 11 additions & 8 deletions kernel/ftrace/hook-func/hook_func.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#include <linux/version.h>
#include <linux/ftrace.h>
#include <linux/kallsyms.h>
#include <linux/security.h>

#define MODULE_NAME "hook_func"

struct ftrace_hook {
const char *name;
Expand Down Expand Up @@ -31,9 +34,9 @@ static int hook_mmap_file(struct file *file, unsigned long prot,
{
int ret;

pr_info("[mmap_file] hook start\n");
pr_info("<%s> [mmap_file] hook start\n", MODULE_NAME);
ret = real_mmap_file(file, prot, flags);
pr_info("[mmap_file] hook done, ret: %d\n", ret);
pr_info("<%s> [mmap_file] hook done, ret: %d\n", MODULE_NAME, ret);

return ret;
}
Expand All @@ -47,7 +50,7 @@ static int resolve_hook_addr(struct ftrace_hook *hook)
{
hook->address = kallsyms_lookup_name(hook->name);
if (!hook->address) {
pr_err("[resolve addr] failed for: %s\n", hook->name);
pr_err("<%s> [resolve addr] failed for: %s\n", MODULE_NAME, hook->name);
return -ENOENT;
}

Expand All @@ -58,21 +61,21 @@ static int resolve_hook_addr(struct ftrace_hook *hook)
static void notrace mmap_file_cb(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *ops, struct pt_regs *regs)
{
pr_info("[mmap_file] start, ip: 0x%lx, parent_ip: 0x%lx\n", ip, parent_ip);
pr_info("<%s> [mmap_file] start, ip: 0x%lx, parent_ip: 0x%lx\n", MODULE_NAME, ip, parent_ip);
if (!regs) {
pr_info("[%s] invalid regs\n", __func__);
pr_info("<%s> [%s] invalid regs\n", MODULE_NAME, __func__);
return ;
}
struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops);

if (!within_module(parent_ip, THIS_MODULE)) {
pr_info("[mmap_file_cb:] %s not module\n", hook->name);
pr_info("<%s> [mmap_file_cb:] %s not module\n", MODULE_NAME, hook->name);
#ifdef CONFIG_ARM64
pr_info("[mmap_file_cb] ------------ ARM64 ---------\n");
pr_info("<%s> [mmap_file_cb] ------------ ARM64 ---------\n", MODULE_NAME);
if (hook)
regs->pc = (unsigned long)hook->function;
#else
pr_info("[mmap_file_cb] ------------ NORMAL ---------\n");
pr_info("<%s> [mmap_file_cb] ------------ NORMAL ---------\n", MODULE_NAME);
if (hook)
regs->ip = (unsigned long)hook->function;
#endif
Expand Down
11 changes: 11 additions & 0 deletions kernel/hookmanager/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
obj-m := demo_test.o
ccflags-y := -std=gnu99 -Wno-declaration-after-statement -O3
cwd := $(shell pwd)

kdir := /lib/modules/$(shell uname -r)/build

all:
make -C ${kdir} M=${cwd} modules

clean:
make -C ${kdir} M=${cwd} clean
125 changes: 125 additions & 0 deletions kernel/hookmanager/demo_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/lsm_uos_hook_manager.h>

#define MODULE_NAME "demo_test"

typedef struct td_hook_entry {
int hook_id;
struct uos_hook_cb_entry cb;
}td_hook_entry_t;

int td_path_rename(const struct path *old_dir, struct dentry *old_dentry,const struct path *new_dir, struct dentry *new_dentry, unsigned int flags)
{
printk("curent: %s %s: test\n", current->comm, __FUNCTION__);

return 0;
}
int td_path_mkdir (const struct path *dir, struct dentry *dentry, umode_t mode)
{
printk("curent: %s %s: test\n", current->comm, __FUNCTION__);

return 0;
}

static td_hook_entry_t entries[] = {
#if 1
{
.hook_id = UOS_PATH_RENAME,
.cb =
{
.owner = MODULE_NAME,
.cb_addr = (unsigned long)td_path_rename,
.ret_type = UOS_HOOK_RET_TY_INT,
.arg_len = 4,
},
},
#endif
#if 1
{
.hook_id = UOS_PATH_MKDIR,
.cb =
{
.owner = MODULE_NAME,
.cb_addr = (unsigned long)td_path_mkdir,
.ret_type = UOS_HOOK_RET_TY_INT,
.arg_len = 3,
},
},
#endif
{
.hook_id = UOS_HOOK_NONE,
},
};


int td_uos_manager_register_hook(void)
{
int i = 0, j = 0;
int error = 0;

for (; entries[i].hook_id != UOS_HOOK_NONE; i++) {
error = uos_hook_register(entries[i].hook_id, &entries[i].cb);
if (error) {
printk("Failed to register hook %d, hook_id = %d\n", i, entries[i].hook_id);
break;
}
}

if (entries[i].hook_id == UOS_HOOK_NONE)
return 0;

for (; j < i; j++) {
error = uos_hook_cancel(entries[j].hook_id, entries[j].cb.owner);
if (error)
printk("Failed to cancel hook %d\n", j);
}

return -1;
}

void td_uos_manager_cancel_hook(void)
{
int i = 0;
int error = 0;

for (; entries[i].hook_id != UOS_HOOK_NONE; i++) {
error = uos_hook_cancel(entries[i].hook_id, entries[i].cb.owner);
if (error)
printk("Failed to cancel hook %d, hook_id = %d\n", i, entries[i].hook_id);
}
}

int __init init_module(void)
{
int error = 0;

#ifdef CONFIG_SECURITY_PATH
printk("CONFIG_SECURITY_PATH is defined\n");
#endif


pr_info("start to init uos hook demo\n");
error = td_uos_manager_register_hook();
if (error) {
pr_info("failed to registe hook\n");
return -1;
}

pr_info("finish to init uos hook demo\n");
return 0;
}

void __exit cleanup_module(void)
{
td_uos_manager_cancel_hook();
pr_info("exit the uos hook demo\n");
}

MODULE_LICENSE("GPL");
MODULE_AUTHOR("jouyouyun");
MODULE_DESCRIPTION("The demo for uos lsm hook manager");


4 changes: 2 additions & 2 deletions kernel/kprobe/Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
obj-m := kprobe_func.o
obj-m := kprobe.o

CROSS_COMPILE=''

KDIR := /lib/modules/$(shell uname -r)/build
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -f *.ko *.o *.mod.o *.mod.c .*.cmd *.symvers modul*
rm -f *.ko *.o *.mod *.mod.o *.mod.c .*.cmd *.symvers modul*
26 changes: 13 additions & 13 deletions kernel/kprobe/kprobe.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <linux/module.h>
#include <linux/kprobes.h>

#define MODULE_NAME "kprobe"
#define MAX_SYMBOL_LEN 64
static char symbol[MAX_SYMBOL_LEN] = "security_mmap_file";
module_param_string(symbol, symbol, sizeof(symbol), 0644);
Expand All @@ -15,13 +16,12 @@ static struct kprobe kp = {
static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
#ifdef CONFIG_X86
pr_info("<%s> pre_handler: p->addr = %pF, ip = %lx, flags = 0x%lx\n",
p->symbol_name, p->addr, regs->ip, regs->flags);
pr_info("[%s] <%s> pre_handler: p->addr = %pF, ip = %lx, flags = 0x%lx\n",
MODULE_NAME, p->symbol_name, p->addr, regs->ip, regs->flags);
#endif
#ifdef CONFIG_ARM64
pr_info("<%s> pre_handler: p->addr = %pF, pc = 0x%lx,"
" pstate = 0x%lx\n",
p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate);
pr_info("[%s] <%s> pre_handler: p->addr = %pF, pc = 0x%lx, pstate = 0x%lx\n",
MODULE_NAME, p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate);
#endif

/* A dump_stack() here will give a stack backtrace */
Expand All @@ -33,12 +33,12 @@ static void handler_post(struct kprobe *p, struct pt_regs *regs,
unsigned long flags)
{
#ifdef CONFIG_X86
pr_info("<%s> post_handler: p->addr = %pF, flags = 0x%lx\n",
p->symbol_name, p->addr, regs->flags);
pr_info("[%s] <%s> post_handler: p->addr = %pF, flags = 0x%lx\n",
MODULE_NAME, p->symbol_name, p->addr, regs->flags);
#endif
#ifdef CONFIG_ARM64
pr_info("<%s> post_handler: p->addr = %pF, pstate = 0x%lx\n",
p->symbol_name, p->addr, (long)regs->pstate);
pr_info("[%s] <%s> post_handler: p->addr = %pF, pstate = 0x%lx\n",
MODULE_NAME, p->symbol_name, p->addr, (long)regs->pstate);
#endif
}

Expand All @@ -49,7 +49,7 @@ static void handler_post(struct kprobe *p, struct pt_regs *regs,
*/
static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
{
pr_info("fault_handler: p->addr = %pF, trap #%dn", p->addr, trapnr);
pr_info("[%s] fault_handler: p->addr = %pF, trap #%dn", MODULE_NAME, p->addr, trapnr);
/* Return 0 because we don't handle the fault. */
return 0;
}
Expand All @@ -63,17 +63,17 @@ static int __init kprobe_init(void)

ret = register_kprobe(&kp);
if (ret < 0) {
pr_err("register_kprobe failed, returned %d\n", ret);
pr_err("[%s] register_kprobe failed, returned %d\n", MODULE_NAME, ret);
return ret;
}
pr_info("Planted kprobe at %pF\n", kp.addr);
pr_info("[%s] Planted kprobe at %pF\n", MODULE_NAME, kp.addr);
return 0;
}

static void __exit kprobe_exit(void)
{
unregister_kprobe(&kp);
pr_info("kprobe at %pF unregistered\n", kp.addr);
pr_info("[%s] kprobe at %pF unregistered\n", MODULE_NAME, kp.addr);
}

module_init(kprobe_init)
Expand Down

0 comments on commit 29d7bed

Please sign in to comment.