From 057ac6de568d1d37e49a22e022a3297798eb0ed5 Mon Sep 17 00:00:00 2001 From: Alexander Aksenov Date: Thu, 19 Jun 2014 14:44:50 +0400 Subject: [PATCH] [IMPROVE] Comm filter for web apps Change-Id: If736b60063f282d1c30bd142604f46ce9d6e9565 Signed-off-by: Alexander Aksenov --- parser/msg_parser.c | 4 +- parser/msg_parser.h | 1 + parser/us_inst.c | 4 +- us_manager/helper.c | 4 +- us_manager/pf/pf_group.c | 32 +++++++++++++++- us_manager/pf/pf_group.h | 1 + us_manager/pf/proc_filters.c | 88 ++++++++++++++++++++++++++++++++++++++++++++ us_manager/pf/proc_filters.h | 6 +++ 8 files changed, 133 insertions(+), 7 deletions(-) diff --git a/parser/msg_parser.c b/parser/msg_parser.c index 8ca60af..6555ec5 100644 --- a/parser/msg_parser.c +++ b/parser/msg_parser.c @@ -133,10 +133,9 @@ struct app_info_data *create_app_info(struct msg_buf *mb) } ai->app_type = (enum APP_TYPE)app_type; + ai->app_id = ta_id; ai->exec_path = exec_path; - put_string(ta_id); - return ai; free_ai: @@ -160,6 +159,7 @@ free_ta_id: void destroy_app_info(struct app_info_data *ai) { put_string(ai->exec_path); + put_string(ai->app_id); kfree(ai); } diff --git a/parser/msg_parser.h b/parser/msg_parser.h index a097d71..78140f2 100644 --- a/parser/msg_parser.h +++ b/parser/msg_parser.h @@ -61,6 +61,7 @@ enum { struct app_info_data { enum APP_TYPE app_type; /**< Application type. */ pid_t tgid; /**< Application PID. */ + char *app_id; /**< Application ID */ char *exec_path; /**< Application execution path. */ }; diff --git a/parser/us_inst.c b/parser/us_inst.c index 108712d..4baf1a6 100644 --- a/parser/us_inst.c +++ b/parser/us_inst.c @@ -127,8 +127,10 @@ static int get_pfg_by_app_info(struct app_info_data *app_info, struct pf_group * } else *pfg = get_pf_group_by_tgid(app_info->tgid, dentry); break; - case AT_TIZEN_NATIVE_APP: case AT_TIZEN_WEB_APP: + *pfg = get_pf_group_by_comm(app_info->app_id, dentry); + break; + case AT_TIZEN_NATIVE_APP: case AT_COMMON_EXEC: pf_dentry: *pfg = get_pf_group_by_dentry(dentry, dentry); diff --git a/us_manager/helper.c b/us_manager/helper.c index 6dbb8c0..d9b1b7a 100644 --- a/us_manager/helper.c +++ b/us_manager/helper.c @@ -511,10 +511,8 @@ static int ret_handler_comm(struct kretprobe_instance *ri, struct pt_regs *regs) return 0; task = ((struct comm_data *)ri->data)->task; - if (sspt_proc_get_by_task(task) == NULL) - return 0; - proc_comm_msg(task); + check_task_and_install(task); return 0; } diff --git a/us_manager/pf/pf_group.c b/us_manager/pf/pf_group.c index 1bffa44..2d2051e 100644 --- a/us_manager/pf/pf_group.c +++ b/us_manager/pf/pf_group.c @@ -162,6 +162,7 @@ static void free_pfg(struct pf_group *pfg) struct pl_struct *pl; free_img_proc(pfg->i_proc); + free_pf(&pfg->filter); list_for_each_entry(pl, &pfg->proc_list, list) sspt_proc_del_filter(pl->proc, pfg); kfree(pfg); @@ -273,6 +274,34 @@ struct pf_group *get_pf_group_by_tgid(pid_t tgid, void *priv) EXPORT_SYMBOL_GPL(get_pf_group_by_tgid); /** + * @brief Get pf_group struct by comm + * + * @param comm Task comm + * @param priv Private data + * @return Pointer on pf_group struct + */ +struct pf_group *get_pf_group_by_comm(char *comm, void *priv) +{ + struct pf_group *pfg; + + list_for_each_entry(pfg, &pfg_list, list) { + if (check_pf_by_comm(&pfg->filter, comm)) + return pfg; + } + + pfg = create_pfg(); + if (pfg == NULL) + return NULL; + + set_pf_by_comm(&pfg->filter, comm, priv); + + add_pfg_by_list(pfg); + + return pfg; +} +EXPORT_SYMBOL_GPL(get_pf_group_by_comm); + +/** * @brief Get pf_group struct for each process * * @param priv Private data @@ -414,7 +443,8 @@ void call_page_fault(struct task_struct *task, unsigned long page_addr) struct sspt_proc *proc = NULL; list_for_each_entry(pfg, &pfg_list, list) { - if (check_task_f(&pfg->filter, task) == NULL) + if (ignore_pf(&pfg->filter) || + (check_task_f(&pfg->filter, task) == NULL)) continue; proc = get_proc_by_pfg(pfg, task); diff --git a/us_manager/pf/pf_group.h b/us_manager/pf/pf_group.h index 2e1f396..2065768 100644 --- a/us_manager/pf/pf_group.h +++ b/us_manager/pf/pf_group.h @@ -33,6 +33,7 @@ struct sspt_proc; struct pf_group *get_pf_group_by_dentry(struct dentry *dentry, void *priv); struct pf_group *get_pf_group_by_tgid(pid_t tgid, void *priv); +struct pf_group *get_pf_group_by_comm(char *comm, void *priv); struct pf_group *get_pf_group_dumb(void *priv); void put_pf_group(struct pf_group *pfg); diff --git a/us_manager/pf/proc_filters.c b/us_manager/pf/proc_filters.c index 7efccda..1b08d9d 100644 --- a/us_manager/pf/proc_filters.c +++ b/us_manager/pf/proc_filters.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "proc_filters.h" #include @@ -59,6 +60,11 @@ static struct task_struct *call_by_dentry(struct proc_filter *self, return NULL; } +static inline void free_by_dentry(struct proc_filter *self) +{ + return; +} + static struct task_struct *call_by_tgid(struct proc_filter *self, struct task_struct *task) { @@ -70,6 +76,28 @@ static struct task_struct *call_by_tgid(struct proc_filter *self, return NULL; } +static inline void free_by_tgid(struct proc_filter *self) +{ + return; +} + +static struct task_struct *call_by_comm(struct proc_filter *self, + struct task_struct *task) +{ + char *comm = (char *)self->data; + size_t len = strnlen(comm, TASK_COMM_LEN); + + if (!strncmp(comm, task->comm, len)) + return task; + + return NULL; +} + +static inline void free_by_comm(struct proc_filter *self) +{ + kfree(self->data); +} + /* Dumb call. Each task is exactly what we are looking for :) */ static struct task_struct *call_dumb(struct proc_filter *self, struct task_struct *task) @@ -108,6 +136,25 @@ void set_pf_by_tgid(struct proc_filter *pf, pid_t tgid, void *priv) } /** + * @brief Fill proc_filter struct for given comm + * + * @param pf Pointer to the proc_filter struct + * @param comm Task comm + * @param priv Private data + * @return Void + */ +void set_pf_by_comm(struct proc_filter *pf, char *comm, void *priv) +{ + size_t len = strnlen(comm, TASK_COMM_LEN); + + pf->call = &call_by_comm; + pf->data = kmalloc(len, GFP_KERNEL); + memset(pf->data, 0, len); + memcpy(pf->data, comm, len - 1); + pf->priv = priv; +} + +/** * @brief Filling pf_group struct for each process * * @param pf Pointer to the proc_filter struct @@ -122,6 +169,22 @@ void set_pf_dumb(struct proc_filter *pf, void *priv) } /** + * @brief Free proc_filter struct + * + * @param filter Pointer to the proc_filter struct + * @return Void + */ +void free_pf(struct proc_filter *filter) +{ + if (filter->call == &call_by_dentry) + free_by_dentry(filter); + else if (filter->call == &call_by_tgid) + free_by_tgid(filter); + else if (filter->call == &call_by_comm) + free_by_comm(filter); +} + +/** * @brief Check pf_group struct by dentry * * @param filter Pointer to the proc_filter struct @@ -151,6 +214,21 @@ int check_pf_by_tgid(struct proc_filter *filter, pid_t tgid) } /** + * @brief Check proc_filter struct by comm + * + * @param filter Pointer to the proc_filter struct + * @param comm Task comm + * @return + * - 0 - false + * - 1 - true + */ +int check_pf_by_comm(struct proc_filter *filter, char *comm) +{ + return ((filter->call == &call_by_comm) && (filter->data != NULL) && + (!strncmp(filter->data, comm, TASK_COMM_LEN))); +} + +/** * @brief Dumb check always true if filter is a dumb one * * @param filter Pointer to the proc_filter struct @@ -176,3 +254,13 @@ struct dentry *get_dentry_by_pf(struct proc_filter *filter) return NULL; } + +/* Check function for call_page_fault() and other frequently called +filter-check functions. It is used to call event-oriented and long-term filters +only on specified events, but not every time memory map is changed. When +iteraiting over the filters list, call this function on each step passing here +pointer on filter. If it returns 1 then the filter should not be called. */ +int ignore_pf(struct proc_filter *filter) +{ + return filter->call == &call_by_comm; +} diff --git a/us_manager/pf/proc_filters.h b/us_manager/pf/proc_filters.h index 730f9d5..3cfe1f9 100644 --- a/us_manager/pf/proc_filters.h +++ b/us_manager/pf/proc_filters.h @@ -54,12 +54,18 @@ struct proc_filter { void set_pf_by_dentry(struct proc_filter *pf, struct dentry *dentry, void *priv); void set_pf_by_tgid(struct proc_filter *pf, pid_t tgid, void *priv); +void set_pf_by_comm(struct proc_filter *pf, char *comm, void *priv); void set_pf_dumb(struct proc_filter *pf, void *priv); int check_pf_by_dentry(struct proc_filter *filter, struct dentry *dentry); int check_pf_by_tgid(struct proc_filter *filter, pid_t tgid); +int check_pf_by_comm(struct proc_filter *filter, char *comm); int check_pf_dumb(struct proc_filter *filter); struct dentry *get_dentry_by_pf(struct proc_filter *filter); +void free_pf(struct proc_filter *filter); + +int ignore_pf(struct proc_filter *filter); + #endif /* _PROC_FILTERS_H */ -- 2.7.4