[FEATURE] implement /un/register_syscall()
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Mon, 24 Jun 2013 11:43:18 +0000 (15:43 +0400)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Mon, 24 Jun 2013 12:03:58 +0000 (16:03 +0400)
ks_features/Makefile.am
ks_features/features_data.h
ks_features/ks_features.c
ks_features/ks_features.h
ks_features/syscall_list.h

index bef7b30..f670827 100644 (file)
@@ -5,8 +5,9 @@ module_dir = $(realpath $(top_srcdir)/src/modules/ks_features)
 module_name = swap_ks_features
 cross_compiler = $(subst gcc,,$(CC))
 
-#inlude_opt = -I$(realpath $(top_srcdir)/src/modules/kprobe) \
-#             -I$(realpath $(top_srcdir)/src/modules/kprobe/arch)
+inlude_opt = -I$(realpath $(top_srcdir)/src/modules/kprobe) \
+             -I$(realpath $(top_srcdir)/src/modules/kprobe/arch) \
+             -I$(realpath $(top_srcdir)/src/modules/ksyms)
 extra_cflags = "$(inlude_opt) $(board_opt)"
 
 all-local:
index a0df130..5fe0e14 100644 (file)
@@ -1,36 +1,27 @@
 #ifndef _FEATURES_DATA_H
 #define _FEATURES_DATA_H
 
-#include <linux/types.h>
 #include "syscall_list.h"
 
-#define X(x) #x
-static const char *const syscall_name[] = {
-       SYSCALL_LIST
-};
-#undef X
-
-enum {
-       syscall_name_cnt = sizeof(syscall_name) / sizeof(char *)
-};
-
 #define X(x) id_##x
 enum syscall_id {
        SYSCALL_LIST
 };
 #undef X
 
-static char sys_counter[syscall_name_cnt] = { 0 };
-
 static enum syscall_id id_file[] = {
        id_sys_acct,
        id_sys_mount,
        id_sys_umount,
        id_sys_truncate,
-       id_sys_stat,
+/* TODO:
+ *     id_sys_stat,
+ */
        id_sys_statfs,
        id_sys_statfs64,
-       id_sys_lstat,
+/* TODO:
+ *     id_sys_lstat,
+ */
        id_sys_stat64,
        id_sys_fstat64,
        id_sys_lstat64,
@@ -77,7 +68,9 @@ static enum syscall_id id_file[] = {
        id_sys_fchmodat,
        id_sys_fchownat,
        id_sys_openat,
-       id_sys_newfstatat,
+/* TODO:
+ *     id_sys_newfstatat,
+ */
        id_sys_readlinkat,
        id_sys_utimensat,
        id_sys_fanotify_mark,
@@ -133,7 +126,9 @@ static enum syscall_id id_process[] = {
        id_sys_exit_group,
        id_sys_wait4,
        id_sys_waitid,
-       id_sys_waitpid,
+/* TODO:
+ *     id_sys_waitpid,
+ */
        id_sys_rt_tgsigqueueinfo,
        id_sys_unshare,
        id_sys_fork,
@@ -148,7 +143,9 @@ static enum syscall_id id_process[] = {
 static enum syscall_id id_signal[] = {
        id_sys_sigpending,
        id_sys_sigprocmask,
-       id_sys_sigaltstack,
+/* TODO:
+ *     id_sys_sigaltstack,
+ */
 /* TODO: add support CONFIG_OLD_SIGSUSPEND and CONFIG_OLD_SIGSUSPEND3
  *     id_sys_sigsuspend,
  *     id_sys_sigsuspend,
@@ -161,7 +158,9 @@ static enum syscall_id id_signal[] = {
        id_sys_rt_tgsigqueueinfo,
        id_sys_kill,
        id_sys_tgkill,
-       id_sys_signal,
+/* TODO:
+ *     id_sys_signal,
+ */
        id_sys_pause,
        id_sys_signalfd,
        id_sys_signalfd4
@@ -197,7 +196,9 @@ static enum syscall_id id_desc[] = {
        id_sys_fchmodat,
        id_sys_fchownat,
        id_sys_openat,
-       id_sys_newfstatat,
+/* TODO:
+ *     id_sys_newfstatat,
+ */
        id_sys_readlinkat,
        id_sys_utimensat,
        id_sys_splice,
@@ -222,30 +223,4 @@ static enum syscall_id id_desc[] = {
        id_sys_setns
 };
 
-struct feature {
-       size_t cnt;
-       enum syscall_id *feature_list;
-};
-
-#define CREATE_FEATURE(x)                              \
-{                                                      \
-       .cnt = sizeof(x) / sizeof(enum syscall_id),     \
-       .feature_list = x                               \
-}
-
-static struct feature features[] = {
-       CREATE_FEATURE(id_file),
-       CREATE_FEATURE(id_irq),
-       CREATE_FEATURE(id_net),
-       CREATE_FEATURE(id_process),
-       CREATE_FEATURE(id_signal),
-       CREATE_FEATURE(id_desc)
-};
-
-#undef CREATE_FEATURE
-
-enum {
-       feature_cnt = sizeof(features) / sizeof(struct feature)
-};
-
 #endif /* _FEATURES_DATA_H */
index 1dd1507..4b5e832 100644 (file)
+#include <linux/module.h>
+#include <asm/errno.h>
+#include <ksyms.h>
+#include <dbi_kprobes.h>
 #include "ks_features.h"
 #include "features_data.h"
-#include <asm/errno.h>
-#include <linux/module.h>
+#include "syscall_list.h"
+
+
+struct feature {
+       size_t cnt;
+       enum syscall_id *feature_list;
+};
+
+struct ks_probe {
+       struct jprobe jp;
+       struct kretprobe rp;
+       int counter;
+};
+
+
+#define CREATE_JP(name)                                                \
+{                                                              \
+       .entry = NULL,                                          \
+       .pre_entry = NULL                                       \
+}
+
+#define CREATE_RP(name)                                                \
+{                                                              \
+       .entry_handler = NULL,                                  \
+       .handler = NULL                                         \
+}
+
+#define CREATE_FEATURE(x)                                      \
+{                                                              \
+       .cnt = sizeof(x) / sizeof(enum syscall_id),             \
+       .feature_list = x                                       \
+}
+
+
+#define X(x) #x
+static const char *const syscall_name[] = {
+       SYSCALL_LIST
+};
+#undef X
+
+enum {
+       syscall_name_cnt = sizeof(syscall_name) / sizeof(char *)
+};
+
+
+#define X(x)                                                   \
+{                                                              \
+       .jp = CREATE_JP(x),                                     \
+       .rp = CREATE_RP(x),                                     \
+       .counter = 0                                            \
+}
+
+static struct ks_probe ksp[] = {
+       SYSCALL_LIST
+};
+#undef X
+
+
+static struct feature features[] = {
+       CREATE_FEATURE(id_file),
+       CREATE_FEATURE(id_irq),
+       CREATE_FEATURE(id_net),
+       CREATE_FEATURE(id_process),
+       CREATE_FEATURE(id_signal),
+       CREATE_FEATURE(id_desc)
+};
+
+enum {
+       feature_cnt = sizeof(features) / sizeof(struct feature)
+};
+
+
+static char *get_sys_name(size_t id)
+{
+       return syscall_name[id];
+}
+
+static int get_counter(size_t id)
+{
+       return ksp[id].counter;
+}
+
+static void inc_counter(size_t id)
+{
+       ++ksp[id].counter;
+}
+
+static void dec_counter(size_t id)
+{
+       --ksp[id].counter;
+}
 
 static int register_syscall(size_t id)
 {
-       printk("register_syscall: %s\n", syscall_name[id]);
-       return 0;
+       int ret;
+       printk("register_syscall: %s\n", get_sys_name(id));
+
+       ret = dbi_register_jprobe(&ksp[id].jp);
+       if (ret)
+               return ret;
+
+       ret = dbi_register_kretprobe(&ksp[id].rp);
+       if (ret)
+               dbi_unregister_jprobe(&ksp[id].jp);
+
+       return ret;
 }
 
 static int unregister_syscall(size_t id)
 {
-       printk("unregister_syscall: %s\n", syscall_name[id]);
+       printk("unregister_syscall: %s\n", get_sys_name(id));
+
+       dbi_unregister_kretprobe(&ksp[id].rp);
+       dbi_unregister_jprobe(&ksp[id].jp);
+
        return 0;
 }
 
 static int install_features(struct feature *f)
 {
-       size_t i, num;
+       size_t i, id;
 
        for (i = 0; i < f->cnt; ++i) {
-               num = f->feature_list[i];
+               id = f->feature_list[i];
 
-               if (sys_counter[num] == 0) {
-                       int ret = register_syscall(num);
+               if (get_counter(id) == 0) {
+                       int ret = register_syscall(id);
                        if (ret) {
                                /* TODO: error */
                                return ret;
                        }
                }
 
-               ++sys_counter[num];
+               inc_counter(id);
        }
 
        return 0;
@@ -38,20 +145,20 @@ static int install_features(struct feature *f)
 
 static int uninstall_features(struct feature *f)
 {
-       size_t i, num;
+       size_t i, id;
 
        for (i = 0; i < f->cnt; ++i) {
-               num = f->feature_list[i];
+               id = f->feature_list[i];
 
-               if (sys_counter[num] == 0) {
+               if (get_counter(id) == 0) {
                        /* TODO: error */
                        return -EINVAL;
                }
 
-               --sys_counter[num];
+               dec_counter(id);
 
-               if (sys_counter[num] == 0) {
-                       int ret = unregister_syscall(num);
+               if (get_counter(id) == 0) {
+                       int ret = unregister_syscall(id);
                        if (ret) {
                                /* TODO: error */
                                return ret;
@@ -70,7 +177,7 @@ static struct feature *get_feature(enum feature_id id)
        return &features[id];
 }
 
-int set_features(enum feature_id id)
+int set_feature(enum feature_id id)
 {
        struct feature *f = get_feature(id);
 
@@ -79,8 +186,9 @@ int set_features(enum feature_id id)
 
        return install_features(f);
 }
+EXPORT_SYMBOL_GPL(set_feature);
 
-int unset_features(enum feature_id id)
+int unset_feature(enum feature_id id)
 {
        struct feature *f = get_feature(id);
 
@@ -89,10 +197,26 @@ int unset_features(enum feature_id id)
 
        return uninstall_features(f);
 }
+EXPORT_SYMBOL_GPL(unset_feature);
 
 static int __init init_ks_feature(void)
 {
-       return 0;
+       int i;
+       unsigned long addr;
+       char *name;
+
+       for (i = 0; i < syscall_name_cnt; ++i) {
+               name = get_sys_name(i);
+               addr = swap_ksyms(name);
+               if (addr == 0) {
+                       printk("%s() not found\n", name);
+                       return -EFAULT;
+               }
+
+               ksp[i].jp.kp.addr = ksp[i].rp.kp.addr = addr;
+       }
+
+       return 0;
 }
 
 static void __exit exit_ks_feature(void)
@@ -102,13 +226,15 @@ static void __exit exit_ks_feature(void)
 module_init(init_ks_feature);
 module_exit(exit_ks_feature);
 
+MODULE_LICENSE("GPL");
+
 /* debug */
 static void print_feature(struct feature *f)
 {
        size_t i;
 
        for (i = 0; i < f->cnt; ++i) {
-               printk("    feature[%3u]: %s\n", i, syscall_name[f->feature_list[i]]);
+               printk("    feature[%3u]: %s\n", i, get_sys_name(f->feature_list[i]));
        }
 }
 
@@ -129,7 +255,7 @@ void print_all_syscall(void)
 
        printk("SYSCALL:\n");
        for (i = 0; i < syscall_name_cnt; ++i) {
-               printk("    [%2d] %s\n", sys_counter[i], syscall_name[i]);
+               printk("    [%2d] %s\n", get_counter(i), get_sys_name(i));
        }
 }
 /* debug */
index 6e56790..4178990 100644 (file)
@@ -10,8 +10,8 @@ enum feature_id {
        FID_DESC
 };
 
-int set_features(enum feature_id id);
-int unset_features(enum feature_id id);
+int set_feature(enum feature_id id);
+int unset_feature(enum feature_id id);
 
 /* debug */
 void print_features(void);
index 1566b3e..6fa0e2e 100644 (file)
@@ -55,7 +55,7 @@
        X(sys_listen), \
        X(sys_listxattr), \
        X(sys_lstat64), \
-       X(sys_lstat), \
+/* TODO: X(sys_lstat), */ \
        X(sys_mkdirat), \
        X(sys_mkdir), \
        X(sys_mknodat), \
@@ -67,7 +67,7 @@
        X(sys_msgrcv), \
        X(sys_msgsnd), \
        X(sys_name_to_handle_at), \
-       X(sys_newfstatat), \
+/* TODO: X(sys_newfstatat), */ \
        X(sys_old_mmap), \
        X(sys_openat), \
        X(sys_open_by_handle_at), \
        X(sys_shmget), \
        X(sys_shutdown), \
        X(sys_sigaction), \
-       X(sys_sigaltstack), \
+/* TODO: X(sys_sigaltstack), */ \
        X(sys_signalfd4), \
        X(sys_signalfd), \
-       X(sys_signal), \
+/* TODO: X(sys_signal), */ \
        X(sys_sigpending), \
        X(sys_sigprocmask), \
        X(sys_sigsuspend), \
        X(sys_stat64), \
        X(sys_statfs64), \
        X(sys_statfs), \
-       X(sys_stat), \
+/* TODO: X(sys_stat), */ \
        X(sys_swapoff), \
        X(sys_swapon), \
        X(sys_symlinkat), \
        X(sys_vfork), \
        X(sys_vmsplice), \
        X(sys_wait4), \
-       X(sys_waitid), \
-       X(sys_waitpid)
+       X(sys_waitid)
+/* TODO: X(sys_waitpid) */
 
 #endif /* _SYSCALL_LIST_H */