diff options
author | Anastasia Lyupa <a.lyupa@samsung.com> | 2015-07-27 15:52:51 +0300 |
---|---|---|
committer | Alexander Aksenov <a.aksenov@samsung.com> | 2015-12-22 17:25:03 +0300 |
commit | 7bc5abdf674414acc2a2320b7decfcbef10d9205 (patch) | |
tree | 14eb7e29bdf30de3f26eb6f30b65a7c86068b72b /preload | |
parent | 008d1e6444ca222ea8378640a68010f74730a616 (diff) | |
download | swap-modules-7bc5abdf674414acc2a2320b7decfcbef10d9205.tar.gz swap-modules-7bc5abdf674414acc2a2320b7decfcbef10d9205.tar.bz2 swap-modules-7bc5abdf674414acc2a2320b7decfcbef10d9205.zip |
[FEATURE] start ui viewer implementation
preload ui viewer lib during main func execution
Change-Id: Icb4d7432c41518a6f3c35d54aa30d9b9d450a44d
Signed-off-by: Anastasia Lyupa <a.lyupa@samsung.com>
Diffstat (limited to 'preload')
-rw-r--r-- | preload/preload_debugfs.c | 141 | ||||
-rw-r--r-- | preload/preload_module.c | 192 | ||||
-rw-r--r-- | preload/preload_module.h | 2 | ||||
-rw-r--r-- | preload/preload_pd.c | 141 | ||||
-rw-r--r-- | preload/preload_pd.h | 7 | ||||
-rw-r--r-- | preload/preload_probe.c | 1 | ||||
-rw-r--r-- | preload/preload_storage.c | 72 | ||||
-rw-r--r-- | preload/preload_storage.h | 4 |
8 files changed, 533 insertions, 27 deletions
diff --git a/preload/preload_debugfs.c b/preload/preload_debugfs.c index ba3fd667..7e2955b5 100644 --- a/preload/preload_debugfs.c +++ b/preload/preload_debugfs.c @@ -24,6 +24,8 @@ static const char PRELOAD_BINARIES_ADD[] = "bins_add"; static const char PRELOAD_BINARIES_REMOVE[] = "bins_remove"; static const char PRELOAD_CALLER[] = "caller"; static const char PRELOAD_HANDLERS_PATH[] = "handlers_path"; +static const char PRELOAD_UI_VIEWER_PATH[] = "ui_viewer_path"; +static const char PRELOAD_UI_VIEWER_APP_INFO[] = "ui_viewer_app_info"; static const char PRELOAD_LINKER_DATA[] = "linker"; static const char PRELOAD_LINKER_PATH[] = "linker_path"; static const char PRELOAD_LINKER_R_DEBUG_OFFSET[] = "r_debug_offset"; @@ -363,6 +365,126 @@ static const struct file_operations handlers_path_file_ops = { }; +/* =========================================================================== + * = UI VIEWER PATH = + * =========================================================================== + */ + + +static ssize_t ui_viewer_path_write(struct file *file, const char __user *buf, + size_t len, loff_t *ppos) +{ + ssize_t ret; + char *path; + + path = kmalloc(len, GFP_KERNEL); + if (path == NULL) { + ret = -ENOMEM; + goto ui_viewer_path_write_out; + } + + if (copy_from_user(path, buf, len)) { + ret = -EINVAL; + goto ui_viewer_path_write_out; + } + + path[len - 1] = '\0'; + + if (preload_storage_set_ui_viewer_info(path) != 0) { + printk(PRELOAD_PREFIX "Cannot set ui viewer path %s\n", path); + ret = -EINVAL; + goto ui_viewer_path_write_out; + } + + ret = len; + + printk(PRELOAD_PREFIX "Set ui viewer path %s\n", path); + +ui_viewer_path_write_out: + kfree(path); + + return ret; +} + +static const struct file_operations ui_viewer_path_file_ops = { + .owner = THIS_MODULE, + .write = ui_viewer_path_write, +}; + + +/* + * format: + * main:app_path + * + * sample: + * 0x00000d60:/bin/app_sample + */ +static int ui_viewer_add_app_info(const char *buf, size_t len) +{ + int n, ret; + char *app_path; + unsigned long main_addr; + const char fmt[] = "%%lx:/%%%ds"; + char fmt_buf[64]; + + n = snprintf(fmt_buf, sizeof(fmt_buf), fmt, PATH_MAX - 2); + if (n <= 0) + return -EINVAL; + + app_path = kmalloc(PATH_MAX, GFP_KERNEL); + if (app_path == NULL) + return -ENOMEM; + + n = sscanf(buf, fmt_buf, &main_addr, app_path + 1); + if (n != 2) { + ret = -EINVAL; + goto free_app_path; + } + app_path[0] = '/'; + + printk(PRELOAD_PREFIX "Set ui viewer app path %s, main offset 0x%lx\n", app_path, main_addr); + + ret = preload_ui_viewer_data_set(app_path, main_addr); + +free_app_path: + kfree(app_path); + return ret; +} + +static ssize_t write_ui_viewer_app_info(struct file *file, + const char __user *user_buf, + size_t len, loff_t *ppos) +{ + ssize_t ret; + char *buf; + + buf = kmalloc(len, GFP_KERNEL); + if (buf == NULL) { + ret = -ENOMEM; + goto free_buf; + } + + if (copy_from_user(buf, user_buf, len)) { + ret = -EINVAL; + goto free_buf; + } + + buf[len - 1] = '\0'; + + if (ui_viewer_add_app_info(buf, len)) + ret = -EINVAL; + +free_buf: + kfree(buf); + + return ret; +} + +static const struct file_operations ui_viewer_app_info_file_ops = { + .owner = THIS_MODULE, + .write = write_ui_viewer_app_info, +}; + unsigned long preload_debugfs_r_debug_offset(void) @@ -374,7 +496,8 @@ int preload_debugfs_init(void) { struct dentry *swap_dentry, *root, *loader, *open_p, *lib_path, *bin_path, *bin_list, *bin_add, *bin_remove, - *linker_dir, *linker_path, *linker_offset, *handlers_path; + *linker_dir, *linker_path, *linker_offset, *handlers_path, + *ui_viewer_path, *ui_viewer_app_info; int ret; ret = -ENODEV; @@ -471,6 +594,22 @@ int preload_debugfs_init(void) goto remove; } + ui_viewer_path = debugfs_create_file(PRELOAD_UI_VIEWER_PATH, + PRELOAD_DEFAULT_PERMS, root, NULL, + &ui_viewer_path_file_ops); + if (IS_ERR_OR_NULL(ui_viewer_path)) { + ret = -ENOMEM; + goto remove; + } + + ui_viewer_app_info = debugfs_create_file(PRELOAD_UI_VIEWER_APP_INFO, + PRELOAD_DEFAULT_PERMS, root, NULL, + &ui_viewer_app_info_file_ops); + if (IS_ERR_OR_NULL(ui_viewer_app_info)) { + ret = -ENOMEM; + goto remove; + } + return 0; remove: diff --git a/preload/preload_module.c b/preload/preload_module.c index c105fd07..261f64de 100644 --- a/preload/preload_module.c +++ b/preload/preload_module.c @@ -12,15 +12,16 @@ #include <kprobe/swap_kprobes.h> #include <kprobe/swap_kprobes_deps.h> #include <us_manager/us_manager_common.h> +#include <us_manager/pf/pf_group.h> #include <us_manager/sspt/sspt_page.h> #include <us_manager/sspt/sspt_file.h> #include <us_manager/sspt/sspt_proc.h> #include <us_manager/sspt/ip.h> #include <us_manager/callbacks.h> +#include <us_manager/probes/probe_info_new.h> #include <writer/kernel_operations.h> #include <master/swap_initializer.h> #include <writer/swap_msg.h> -#include <task_data/task_data.h> #include "preload.h" #include "preload_probe.h" #include "preload_debugfs.h" @@ -516,6 +517,7 @@ static inline void __write_data_to_msg(char *msg, size_t len, enum mmap_type_t { MMAP_LOADER, MMAP_HANDLERS, + MMAP_UI_VIEWER, MMAP_SKIP }; @@ -535,7 +537,7 @@ static int mmap_entry_handler(struct kretprobe_instance *ri, unsigned long prot = swap_get_karg(regs, 3); struct mmap_priv *priv = (struct mmap_priv *)ri->data; struct dentry *dentry, *loader_dentry; - struct bin_info *hi; + struct bin_info *hi, *vi; priv->type = MMAP_SKIP; if (!check_prot(prot)) @@ -554,12 +556,23 @@ static int mmap_entry_handler(struct kretprobe_instance *ri, return 0; } + vi = preload_storage_get_ui_viewer_info(); + if (vi == NULL) { + printk(PRELOAD_PREFIX "Cannot get ui viewer info [%u %u %s]\n", + current->tgid, current->pid, current->comm); + goto put_hi; + } + loader_dentry = preload_debugfs_get_loader_dentry(); if (dentry == loader_dentry) priv->type = MMAP_LOADER; else if (hi->dentry != NULL && dentry == hi->dentry) priv->type = MMAP_HANDLERS; + else if (vi->dentry != NULL && dentry == vi->dentry) + priv->type = MMAP_UI_VIEWER; + preload_storage_put_handlers_info(vi); +put_hi: preload_storage_put_handlers_info(hi); return 0; @@ -599,6 +612,9 @@ static int mmap_ret_handler(struct kretprobe_instance *ri, case MMAP_HANDLERS: preload_pd_set_handlers_base(pd, vaddr); break; + case MMAP_UI_VIEWER: + preload_pd_set_ui_viewer_base(proc->private_data, vaddr); + break; case MMAP_SKIP: default: break; @@ -658,7 +674,7 @@ static int preload_us_entry(struct uretprobe_instance *ri, struct pt_regs *regs) if (vaddr) { /* save original regs state */ __save_uregs(ri, regs); - print_regs("ORIG", regs, ri); + print_regs("PROBE ORIG", regs, ri); path = preload_pd_get_path(pd); @@ -745,16 +761,14 @@ static int preload_us_ret(struct uretprobe_instance *ri, struct pt_regs *regs) /* restore original regs state */ __restore_uregs(ri, regs); - print_regs("REST", regs, ri); + print_regs("PROBE REST", regs, ri); /* check if preloading done */ if (preload_pd_get_handle(pd)) { preload_pd_set_state(pd, LOADED); - preload_pd_put_path(pd); } else { preload_pd_dec_attempts(pd); preload_pd_set_state(pd, FAILED); - preload_pd_put_path(pd); } } break; @@ -779,7 +793,6 @@ static int preload_us_ret(struct uretprobe_instance *ri, struct pt_regs *regs) case FAILED: if (preload_pd_get_attempts(pd)) { preload_pd_set_state(pd, NOT_LOADED); - preload_pd_put_path(pd); } break; case ERROR: @@ -962,6 +975,171 @@ void preload_unset(void) } + +/* ============================================================================ + * = ui_viewer = + * ============================================================================ + */ + +/* main handler for ui viewer */ +static int preload_ui_viewer_main_eh(struct uretprobe_instance *ri, + struct pt_regs *regs); +static int preload_ui_viewer_main_rh(struct uretprobe_instance *ri, + struct pt_regs *regs); +static struct probe_info_new pin_main = MAKE_URPROBE(preload_ui_viewer_main_eh, + preload_ui_viewer_main_rh, + 0); + +struct ui_viewer_data { + struct dentry *app_dentry; + struct probe_new p_main; + struct pf_group *pfg; +}; + +static struct ui_viewer_data __ui_data; + +static int preload_ui_viewer_data_inst(void) +{ + int ret; + struct pf_group *pfg; + + pfg = get_pf_group_by_dentry(__ui_data.app_dentry, + (void *)__ui_data.app_dentry); + if (pfg == NULL) + return -ENOMEM; + + ret = pin_register(&__ui_data.p_main, pfg, __ui_data.app_dentry); + if (ret) + goto put_g; + + __ui_data.pfg = pfg; + + return 0; +put_g: + put_pf_group(pfg); + return ret; +} + +/* +static void preload_ui_viewer_data_uninst(void) +{ + struct pf_group *pfg = __ui_data.pfg; + + pin_unregister(&__ui_data.p_main, pfg, __ui_data.app_dentry); + + put_pf_group(pfg); + + __ui_data.pfg = NULL; +} +*/ + +static int preload_ui_viewer_init(struct us_ip *ip) +{ + return 0; +} + +static void preload_ui_viewer_exit(struct us_ip *ip) +{ + return; +} + +int preload_ui_viewer_data_set(const char *app_path, unsigned long main_addr) +{ + struct dentry *dentry; + + dentry = dentry_by_path(app_path); + if (dentry == NULL) + return -ENOENT; + + __ui_data.app_dentry = dentry; + __ui_data.p_main.info = &pin_main; + __ui_data.p_main.offset = main_addr; + __ui_data.pfg = NULL; + + preload_ui_viewer_data_inst(); + + return 0; +} + +/* ============================================================================ + * = ui viewer handlers = + * ============================================================================ + */ +static int preload_ui_viewer_main_eh(struct uretprobe_instance *ri, + struct pt_regs *regs) +{ + struct process_data *pd; + struct us_ip *ip = container_of(ri->rp, struct us_ip, retprobe); + unsigned long vaddr = 0; + char __user *path = NULL; + + preload_ui_viewer_init(ip); + + pd = __get_process_data(ri->rp); + + switch (preload_pd_get_ui_viewer_state(pd)) { + case NOT_LOADED: + /* jump to loader code if ready */ + vaddr = preload_pd_get_loader_base(pd) + + preload_debugfs_get_loader_offset(); + if (vaddr) { + /* save original regs state */ + __save_uregs(ri, regs); + print_regs("UI VIEWER ORIG", regs, ri); + + path = preload_pd_get_ui_viewer_path(pd); + + /* set dlopen args: filename, flags */ + swap_set_arg(regs, 0, (unsigned long)path); + swap_set_arg(regs, 1, 2 /* RTLD_NOW */); + + /* do the jump to dlopen */ + __prepare_ujump(ri, regs, vaddr); + /* set new state */ + preload_pd_set_ui_viewer_state(pd, LOADING); + } + break; + default: + break; + } + + return 0; +} + +static int preload_ui_viewer_main_rh(struct uretprobe_instance *ri, struct pt_regs *regs) +{ + struct process_data *pd = __get_process_data(ri->rp); + struct us_ip *ip = container_of(ri->rp, struct us_ip, retprobe); + unsigned long vaddr = 0; + + switch (preload_pd_get_ui_viewer_state(pd)) { + case LOADING: + vaddr = preload_pd_get_loader_base(pd) + + preload_debugfs_get_loader_offset(); + if (vaddr) { + preload_pd_set_handle(pd, + (void __user *)regs_return_value(regs)); + /* restore original regs state */ + __restore_uregs(ri, regs); + print_regs("UI VIEWER REST", regs, ri); + + /* check if preloading is done */ + if (preload_pd_get_handle(pd)) { + preload_pd_set_ui_viewer_state(pd, LOADED); + } else { + preload_pd_set_ui_viewer_state(pd, FAILED); + } + } + default: + break; + } + + preload_ui_viewer_exit(ip); + + return 0; +} + + static int preload_module_init(void) { int ret; diff --git a/preload/preload_module.h b/preload/preload_module.h index 62f0bfd4..3b1a5731 100644 --- a/preload/preload_module.h +++ b/preload/preload_module.h @@ -26,5 +26,7 @@ void preload_module_write_msg_exit(struct us_ip *ip); struct dentry *get_dentry(const char *filepath); void put_dentry(struct dentry *dentry); +int preload_ui_viewer_data_set(const char *app_path, unsigned long main_addr); + #endif /* __PRELOAD_MODULE_H__ */ diff --git a/preload/preload_pd.c b/preload/preload_pd.c index fcc2e6b7..debd1788 100644 --- a/preload/preload_pd.c +++ b/preload/preload_pd.c @@ -13,17 +13,22 @@ #include "preload_storage.h" #include "preload.h" + struct process_data { enum preload_state_t state; + enum preload_state_t ui_viewer_state; unsigned long loader_base; unsigned long handlers_base; + unsigned long ui_viewer_base; unsigned long data_page; + unsigned long ui_viewer_offset; void __user *handle; long attempts; long refcount; }; static struct bin_info *handlers_info; +static struct bin_info *ui_viewer_info; @@ -112,6 +117,38 @@ static inline void __set_refcount(struct process_data *pd, long refcount) pd->refcount = refcount; } +static inline enum preload_state_t __get_ui_viewer_state(struct process_data *pd) +{ + return pd->ui_viewer_state; +} + +static inline void __set_ui_viewer_state(struct process_data *pd, + enum preload_state_t state) +{ + pd->ui_viewer_state = state; +} + +static inline void __set_ui_viewer_base(struct process_data *pd, + unsigned long addr) +{ + pd->ui_viewer_base = addr; +} + +static inline unsigned long __get_ui_viewer_base(struct process_data *pd) +{ + return pd->ui_viewer_base; +} + +static inline void __set_ui_viewer_offset(struct process_data *pd, + unsigned long offset) +{ + pd->ui_viewer_offset = offset; +} + +static inline char __user *__get_ui_viewer_path(struct process_data *pd) +{ + return (char *)(pd->data_page + pd->ui_viewer_offset); +} @@ -123,6 +160,12 @@ static int __pd_create_on_demand(void) return -EINVAL; } + if (ui_viewer_info == NULL) { + ui_viewer_info = preload_storage_get_ui_viewer_info(); + if (ui_viewer_info == NULL) + return -EINVAL; + } + return 0; } @@ -140,13 +183,47 @@ void preload_pd_set_state(struct process_data *pd, enum preload_state_t state) { if (pd == NULL) { printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n", __LINE__, - current->tgid, current->comm); + current->tgid, current->comm); return; } __set_state(pd, state); } +enum preload_state_t preload_pd_get_ui_viewer_state(struct process_data *pd) +{ + if (pd == NULL) + return 0; + + return __get_ui_viewer_state(pd); +} + +void preload_pd_set_ui_viewer_state(struct process_data *pd, + enum preload_state_t state) +{ + if (pd == NULL) { + printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n", __LINE__, + current->tgid, current->comm); + return; + } + + __set_ui_viewer_state(pd, state); +} + +char __user *preload_pd_get_path(struct process_data *pd) +{ + char __user *path = __get_path(pd); + + return path; +} + +char __user *preload_pd_get_ui_viewer_path(struct process_data *pd) +{ + char __user *path = __get_ui_viewer_path(pd); + + return path; +} + unsigned long preload_pd_get_loader_base(struct process_data *pd) { if (pd == NULL) @@ -173,11 +250,30 @@ void preload_pd_set_handlers_base(struct process_data *pd, unsigned long vaddr) __set_handlers_base(pd, vaddr); } +unsigned long preload_pd_get_ui_viewer_base(struct process_data *pd) +{ + if (pd == NULL) + return 0; + + return __get_ui_viewer_base(pd); +} + +void preload_pd_set_ui_viewer_base(struct process_data *pd, unsigned long vaddr) +{ + if (pd == NULL) { + printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n", __LINE__, + current->tgid, current->comm); + return; + } + + __set_ui_viewer_base(pd, vaddr); +} + void preload_pd_put_path(struct process_data *pd) { if (pd == NULL) { printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n", __LINE__, - current->tgid, current->comm); + current->tgid, current->comm); return; } @@ -187,15 +283,6 @@ void preload_pd_put_path(struct process_data *pd) __set_data_page(pd, 0); } -char __user *preload_pd_get_path(struct process_data *pd) -{ - char __user *path = __get_path(pd); - - return path; -} - - - void *preload_pd_get_handle(struct process_data *pd) { if (pd == NULL) @@ -281,13 +368,15 @@ struct process_data *preload_pd_get(struct sspt_proc *proc) return (struct process_data *)proc->private_data; } -static unsigned long make_preload_path(void) +static unsigned long make_preload_path(unsigned long *offset) { unsigned long page = -EINVAL; - if (handlers_info) { - const char *path = handlers_info->path; - size_t len = strnlen(path, PATH_MAX); + if (handlers_info && ui_viewer_info) { + const char *probe_path = handlers_info->path; + size_t probe_len = strnlen(probe_path, PATH_MAX); + const char *ui_viewer_path = ui_viewer_info->path; + size_t ui_viewer_len = strnlen(ui_viewer_path, PATH_MAX); down_write(¤t->mm->mmap_sem); page = swap_do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_WRITE, @@ -300,8 +389,17 @@ static unsigned long make_preload_path(void) goto out; } - /* set preload_library path */ - if (copy_to_user((void __user *)page, path, len) != 0) + /* set preload_libraries paths */ + if (copy_to_user((void __user *)page, probe_path, + probe_len) != 0) + printk(KERN_ERR PRELOAD_PREFIX + "Cannot copy string to user!\n"); + + /* split paths with 0 value */ + *offset = probe_len + 1; + + if (copy_to_user((void __user *)(page + *offset), + ui_viewer_path, ui_viewer_len) != 0) printk(KERN_ERR PRELOAD_PREFIX "Cannot copy string to user!\n"); } @@ -348,7 +446,7 @@ static void set_already_mapp(struct process_data *pd, struct mm_struct *mm) static struct process_data *do_create_pd(struct task_struct *task) { struct process_data *pd; - unsigned long page; + unsigned long page, offset = 0; int ret; ret = __pd_create_on_demand(); @@ -361,13 +459,14 @@ static struct process_data *do_create_pd(struct task_struct *task) goto create_pd_exit; } - page = make_preload_path(); + page = make_preload_path(&offset); if (IS_ERR_VALUE(page)) { ret = (long)page; goto free_pd; } __set_data_page(pd, page); + __set_ui_viewer_offset(pd, offset); __set_attempts(pd, PRELOAD_MAX_ATTEMPTS); set_already_mapp(pd, task->mm); @@ -416,4 +515,8 @@ void preload_pd_uninit(void) if (handlers_info) preload_storage_put_handlers_info(handlers_info); handlers_info = NULL; + + if (ui_viewer_info) + preload_storage_put_ui_viewer_info(ui_viewer_info); + ui_viewer_info = NULL; } diff --git a/preload/preload_pd.h b/preload/preload_pd.h index bff469dd..31195bb9 100644 --- a/preload/preload_pd.h +++ b/preload/preload_pd.h @@ -17,10 +17,16 @@ struct process_data *preload_pd_get(struct sspt_proc *proc); enum preload_state_t preload_pd_get_state(struct process_data *pd); void preload_pd_set_state(struct process_data *pd, enum preload_state_t state); +enum preload_state_t preload_pd_get_ui_viewer_state(struct process_data *pd); +void preload_pd_set_ui_viewer_state(struct process_data *pd, + enum preload_state_t state); unsigned long preload_pd_get_loader_base(struct process_data *pd); void preload_pd_set_loader_base(struct process_data *pd, unsigned long vaddr); unsigned long preload_pd_get_handlers_base(struct process_data *pd); void preload_pd_set_handlers_base(struct process_data *pd, unsigned long vaddr); +unsigned long preload_pd_get_ui_viewer_base(struct process_data *pd); +void preload_pd_set_ui_viewer_base(struct process_data *pd, + unsigned long vaddr); void *preload_pd_get_handle(struct process_data *pd); void preload_pd_set_handle(struct process_data *pd, void __user *handle); @@ -32,6 +38,7 @@ void preload_pd_dec_refs(struct process_data *pd); long preload_pd_get_refs(struct process_data *pd); char __user *preload_pd_get_path(struct process_data *pd); +char __user *preload_pd_get_ui_viewer_path(struct process_data *pd); void preload_pd_put_path(struct process_data *pd); int preload_pd_init(void); diff --git a/preload/preload_probe.c b/preload/preload_probe.c index 18c9585d..255f8a96 100644 --- a/preload/preload_probe.c +++ b/preload/preload_probe.c @@ -257,6 +257,7 @@ int register_preload_probes(void) return ret; ret = swap_register_probe_type(SWAP_WRITE_MSG, &write_msg_iface); + return ret; } diff --git a/preload/preload_storage.c b/preload/preload_storage.c index e6d1c5d1..1c8db1ae 100644 --- a/preload/preload_storage.c +++ b/preload/preload_storage.c @@ -8,6 +8,7 @@ #include "preload_storage.h" static struct bin_info __handlers_info = { NULL, NULL }; +static struct bin_info __ui_viewer_info = { NULL, NULL }; static struct bin_info __linker_info = { NULL, NULL }; static struct bin_info __libc_info; static struct bin_info __libpthread_info; @@ -64,6 +65,57 @@ static inline void __drop_handlers_info(void) __handlers_info.dentry = NULL; } +static inline struct bin_info *__get_ui_viewer_info(void) +{ + return &__ui_viewer_info; +} + +static inline bool __check_ui_viewer_info(void) +{ + return (__ui_viewer_info.dentry != NULL); /* TODO */ +} + +static inline int __init_ui_viewer_info(char *path) +{ + struct dentry *dentry; + size_t len = strnlen(path, PATH_MAX); + int ret = 0; + + __ui_viewer_info.path = kmalloc(len + 1, GFP_KERNEL); + if (__ui_viewer_info.path == NULL) { + ret = -ENOMEM; + goto init_ui_viewer_fail; + } + + dentry = get_dentry(path); + if (!dentry) { + ret = -ENOENT; + goto init_ui_viewer_fail_free; + } + + strncpy(__ui_viewer_info.path, path, len); + __ui_viewer_info.path[len] = '\0'; + __ui_viewer_info.dentry = dentry; + + return ret; + +init_ui_viewer_fail_free: + kfree(__ui_viewer_info.path); + +init_ui_viewer_fail: + return ret; +} + +static inline void __drop_ui_viewer_info(void) +{ + kfree(__ui_viewer_info.path); + __ui_viewer_info.path = NULL; + + if (__ui_viewer_info.dentry) + put_dentry(__ui_viewer_info.dentry); + __ui_viewer_info.dentry = NULL; +} + static inline struct bin_info *__get_linker_info(void) { return &__linker_info; @@ -139,6 +191,25 @@ void preload_storage_put_handlers_info(struct bin_info *info) { } +int preload_storage_set_ui_viewer_info(char *path) +{ + return __init_ui_viewer_info(path); +} + +struct bin_info *preload_storage_get_ui_viewer_info(void) +{ + struct bin_info *info = __get_ui_viewer_info(); + + if (__check_ui_viewer_info()) + return info; + + return NULL; +} + +void preload_storage_put_ui_viewer_info(struct bin_info *info) +{ +} + int preload_storage_set_linker_info(char *path) { return __init_linker_info(path); @@ -243,5 +314,6 @@ void preload_storage_exit(void) __drop_libpthread_info(); __drop_libc_info(); __drop_handlers_info(); + __drop_ui_viewer_info(); __drop_linker_info(); } diff --git a/preload/preload_storage.h b/preload/preload_storage.h index 2ae16759..2afc1865 100644 --- a/preload/preload_storage.h +++ b/preload/preload_storage.h @@ -11,6 +11,10 @@ int preload_storage_set_handlers_info(char *path); struct bin_info *preload_storage_get_handlers_info(void); void preload_storage_put_handlers_info(struct bin_info *info); +int preload_storage_set_ui_viewer_info(char *path); +struct bin_info *preload_storage_get_ui_viewer_info(void); +void preload_storage_put_ui_viewer_info(struct bin_info *info); + int preload_storage_set_linker_info(char *path); struct bin_info *preload_storage_get_linker_info(void); void preload_storage_put_linker_info(struct bin_info *info); |