}
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:
void destroy_app_info(struct app_info_data *ai)
{
put_string(ai->exec_path);
+ put_string(ai->app_id);
kfree(ai);
}
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. */
};
} 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);
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;
}
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);
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
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);
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);
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/mm_types.h>
+#include <linux/string.h>
#include <linux/fs.h>
#include "proc_filters.h"
#include <us_manager/sspt/sspt.h>
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)
{
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)
}
/**
+ * @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
}
/**
+ * @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
}
/**
+ * @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
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;
+}
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 */