void *data = NULL;
struct sspt_proc *proc;
- proc = sspt_proc_get_by_task(task);
+ proc = sspt_proc_by_task(task);
if (proc)
data = sspt_get_feature_data(proc->feature, feature_id);
file = fget(fd);
if (file) {
int magic = 0;
- if (file->f_dentry && file->f_dentry->d_sb)
- magic = file->f_dentry->d_sb->s_magic;
+ if (file->f_path.dentry && file->f_path.dentry->d_sb)
+ magic = file->f_path.dentry->d_sb->s_magic;
fput(file);
#include <us_manager/probes/register_probes.h>
#include <uprobe/swap_uprobes.h>
- #include <us_manager/sspt/ip.h>
+ #include <us_manager/sspt/sspt_ip.h>
#include <kprobe/swap_kprobes_deps.h>
#include <linux/module.h>
/* TODO FILTER vma */
for (vma = mm->mmap; vma; vma = vma->vm_next) {
if (vma->vm_file &&
- (vma->vm_file->f_dentry == dentry))
+ (vma->vm_file->f_path.dentry == dentry))
/* found */
goto exit;
}
}
static int fbi_probe_get_data_from_direct_addr(const struct fbi_var_data *fbi_i,
- struct us_ip *ip,
+ struct sspt_ip *ip,
struct pt_regs *regs)
{
struct vm_area_struct *vma;
static int fbi_probe_handler(struct uprobe *p, struct pt_regs *regs)
{
- struct us_ip *ip = container_of(p, struct us_ip, uprobe);
+ struct sspt_ip *ip = container_of(p, struct sspt_ip, uprobe);
struct fbi_info *fbi_i = &ip->desc->info.fbi_i;
struct fbi_var_data *fbi_d = NULL;
uint8_t i;
fbi_i->vars = NULL;
}
- void fbi_probe_init(struct us_ip *ip)
+ void fbi_probe_init(struct sspt_ip *ip)
{
ip->uprobe.pre_handler = (uprobe_pre_handler_t)fbi_probe_handler;
}
- void fbi_probe_uninit(struct us_ip *ip)
+ void fbi_probe_uninit(struct sspt_ip *ip)
{
if (ip != NULL)
fbi_probe_cleanup(&ip->desc->info);
}
- static int fbi_probe_register_probe(struct us_ip *ip)
+ static int fbi_probe_register_probe(struct sspt_ip *ip)
{
return swap_register_uprobe(&ip->uprobe);
}
- static void fbi_probe_unregister_probe(struct us_ip *ip, int disarm)
+ static void fbi_probe_unregister_probe(struct sspt_ip *ip, int disarm)
{
__swap_unregister_uprobe(&ip->uprobe, disarm);
}
- static struct uprobe *fbi_probe_get_uprobe(struct us_ip *ip)
+ static struct uprobe *fbi_probe_get_uprobe(struct sspt_ip *ip)
{
return &ip->uprobe;
}
#include <swap-asm/swap_kprobes.h>
-#ifdef CONFIG_ARM
-
-#define regs_return_value(regs) ((regs)->ARM_r0)
-
-#endif
-
-
/* kprobe_status settings */
/** Kprobe hit active */
#define KPROBE_HIT_ACTIVE 0x00000001
int trampoline_probe_handler (struct kprobe *p, struct pt_regs *regs);
- DECLARE_PER_CPU(struct kprobe *, swap_current_kprobe);
extern atomic_t kprobe_count;
extern unsigned long sched_addr;
struct kprobe *swap_kprobe_running(void);
+ void swap_kprobe_running_set(struct kprobe *p);
void swap_reset_current_kprobe(void);
struct kprobe_ctlblk *swap_get_kprobe_ctlblk(void);
- void prepare_singlestep(struct kprobe *p, struct pt_regs *regs);
#endif /* _SWAP_KPROBES_H */
#define _SWAP_KPROBES_DEPS_H
#include <linux/version.h> /* LINUX_VERSION_CODE, KERNEL_VERSION() */
+#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/mempolicy.h>
#include <linux/highmem.h>
#endif
- /*
- * TODO: possibly unnided
- * check and remove swap_preempt_enable_no_resched() call
- */
- #if (defined(MODULE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)))
-
- #ifdef CONFIG_PREEMPT_COUNT
- #define swap_preempt_enable_no_resched() \
- do { \
- barrier(); \
- preempt_count_dec(); \
- } while (0)
- #else /* !CONFIG_PREEMPT_COUNT */
- #define swap_preempt_enable_no_resched() barrier()
- #endif /* CONFIG_PREEMPT_COUNT */
-
- #else /* !(defined(MODULE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) */
-
- #define swap_preempt_enable_no_resched() preempt_enable_no_resched()
-
- #endif /* !(defined(MODULE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) */
-
-
#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 1, 0)
#define task_job(task) (task->jobctl)
#else /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 1, 0) */
unsigned long flags, unsigned long pgoff);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 16, 0)
+#define swap_hlist_add_after(node, prev) hlist_add_behind(node, prev)
+#else /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 16, 0) */
+#define swap_hlist_add_after(node, prev) hlist_add_after(node, prev)
+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 16, 0) */
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 18, 0)
+#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 18, 0) */
#endif /* _SWAP_KPROBES_DEPS_H */
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/mman.h>
+ #include <linux/module.h>
#include <linux/hardirq.h>
#include <linux/list.h>
#include <us_manager/us_manager_common.h>
#include <us_manager/sspt/sspt_proc.h>
- #include "preload_pd.h"
- #include "preload_threads.h"
- #include "preload_debugfs.h"
- #include "preload_storage.h"
- #include "preload.h"
+ #include "loader_pd.h"
+ #include "loader.h"
+ #include "loader_debugfs.h"
+ #include "loader_storage.h"
+ #include "loader_defs.h"
struct pd_t {
unsigned long loader_base;
{
struct file *file = vma->vm_file;
- return (file && (vma->vm_flags & VM_EXEC) && (file->f_dentry == dentry));
+ return (file && (vma->vm_flags & VM_EXEC) &&
+ (file->f_path.dentry == dentry));
}
static inline unsigned long __get_loader_base(struct pd_t *pd)
MAP_ANONYMOUS | MAP_PRIVATE, 0);
up_write(¤t->mm->mmap_sem);
if (IS_ERR_VALUE(page)) {
- printk(KERN_ERR PRELOAD_PREFIX
+ printk(KERN_ERR LOADER_PREFIX
"Cannot alloc page for %u\n", current->tgid);
goto create_pd_fail;
}
/* set handler path */
if (copy_to_user((void __user *)dest, src, len) != 0) {
- printk(KERN_ERR PRELOAD_PREFIX
+ printk(KERN_ERR LOADER_PREFIX
"Cannot copy string to user!\n");
return 0;
}
static void __set_ld_mapped(struct pd_t *pd, struct mm_struct *mm)
{
struct vm_area_struct *vma;
- struct dentry *ld = preload_debugfs_get_loader_dentry();
+ struct dentry *ld = ld_get_loader_dentry();
down_read(&mm->mmap_sem);
if (ld) {
size_t len;
int ret = 0;
- handlers = preload_storage_get_handlers();
+ handlers = ls_get_handlers();
if (handlers == NULL)
return -EINVAL;
hd = kzalloc(sizeof(*hd), GFP_ATOMIC);
if (hd == NULL) {
- printk(KERN_ERR PRELOAD_PREFIX "No atomic mem!\n");
+ printk(KERN_ERR LOADER_PREFIX "No atomic mem!\n");
ret = -ENOMEM;
goto get_handlers_out;
}
hd->dentry = bin->dentry;
hd->offset = offset;
__set_handler_mapped(hd, task->mm);
- __set_attempts(hd, PRELOAD_MAX_ATTEMPTS);
+ __set_attempts(hd, LOADER_MAX_ATTEMPTS);
list_add_tail(&hd->list, &pd->handlers);
/* inc handlers path's on page */
get_handlers_out:
/* TODO Cleanup already created */
- preload_storage_put_handlers();
+ ls_put_handlers();
return ret;
}
- enum ps_t preload_pd_get_state(struct hd_t *hd)
+ enum ps_t lpd_get_state(struct hd_t *hd)
{
if (hd == NULL)
return 0;
return __get_state(hd);
}
+ EXPORT_SYMBOL_GPL(lpd_get_state);
- void preload_pd_set_state(struct hd_t *hd, enum ps_t state)
+ void lpd_set_state(struct hd_t *hd, enum ps_t state)
{
if (hd == NULL) {
- printk(PRELOAD_PREFIX "%d: No handler data! Current %d %s\n",
+ printk(LOADER_PREFIX "%d: No handler data! Current %d %s\n",
__LINE__, current->tgid, current->comm);
return;
}
__set_state(hd, state);
}
- unsigned long preload_pd_get_loader_base(struct pd_t *pd)
+ unsigned long lpd_get_loader_base(struct pd_t *pd)
{
if (pd == NULL)
return 0;
return __get_loader_base(pd);
}
- void preload_pd_set_loader_base(struct pd_t *pd, unsigned long vaddr)
+ void lpd_set_loader_base(struct pd_t *pd, unsigned long vaddr)
{
__set_loader_base(pd, vaddr);
}
- unsigned long preload_pd_get_handlers_base(struct hd_t *hd)
+ unsigned long lpd_get_handlers_base(struct hd_t *hd)
{
if (hd == NULL)
return 0;
return __get_handlers_base(hd);
}
+ EXPORT_SYMBOL_GPL(lpd_get_handlers_base);
- void preload_pd_set_handlers_base(struct hd_t *hd, unsigned long vaddr)
+ void lpd_set_handlers_base(struct hd_t *hd, unsigned long vaddr)
{
__set_handlers_base(hd, vaddr);
}
- char __user *preload_pd_get_path(struct pd_t *pd, struct hd_t *hd)
+ char __user *lpd_get_path(struct pd_t *pd, struct hd_t *hd)
{
unsigned long page = __get_data_page(pd);
unsigned long offset = __get_offset(hd);
- void *preload_pd_get_handle(struct hd_t *hd)
+ void *lpd_get_handle(struct hd_t *hd)
{
if (hd == NULL)
return NULL;
return __get_handle(hd);
}
- void preload_pd_set_handle(struct hd_t *hd, void __user *handle)
+ void lpd_set_handle(struct hd_t *hd, void __user *handle)
{
if (hd == NULL) {
- printk(PRELOAD_PREFIX "%d: No handler data! Current %d %s\n",
+ printk(LOADER_PREFIX "%d: No handler data! Current %d %s\n",
__LINE__, current->tgid, current->comm);
return;
}
__set_handle(hd, handle);
}
- long preload_pd_get_attempts(struct hd_t *hd)
+ long lpd_get_attempts(struct hd_t *hd)
{
if (hd == NULL)
return -EINVAL;
return __get_attempts(hd);
}
- void preload_pd_dec_attempts(struct hd_t *hd)
+ void lpd_dec_attempts(struct hd_t *hd)
{
long attempts;
if (hd == NULL) {
- printk(PRELOAD_PREFIX "%d: No handler data! Current %d %s\n",
+ printk(LOADER_PREFIX "%d: No handler data! Current %d %s\n",
__LINE__, current->tgid, current->comm);
return;
}
__set_attempts(hd, attempts);
}
- struct dentry *preload_pd_get_dentry(struct hd_t *hd)
+ struct dentry *lpd_get_dentry(struct hd_t *hd)
{
return hd->dentry;
}
- struct pd_t *preload_pd_get_parent_pd(struct hd_t *hd)
+ struct pd_t *lpd_get_parent_pd(struct hd_t *hd)
{
return hd->parent;
}
+ EXPORT_SYMBOL_GPL(lpd_get_parent_pd);
- struct pd_t *preload_pd_get(struct sspt_proc *proc)
+ struct pd_t *lpd_get(struct sspt_proc *proc)
{
return (struct pd_t *)proc->private_data;
}
+ EXPORT_SYMBOL_GPL(lpd_get);
- struct hd_t *preload_pd_get_hd(struct pd_t *pd, struct dentry *dentry)
+ struct hd_t *lpd_get_hd(struct pd_t *pd, struct dentry *dentry)
{
struct hd_t *hd;
return NULL;
}
+ EXPORT_SYMBOL_GPL(lpd_get_hd);
static struct pd_t *do_create_pd(struct task_struct *task)
{
kfree(pd);
create_pd_exit:
- printk(KERN_ERR PRELOAD_PREFIX "do_pd_create_pd: error=%d\n", ret);
+ printk(KERN_ERR LOADER_PREFIX "do_pd_create_pd: error=%d\n", ret);
return NULL;
}
{
struct pd_t *pd;
- pd = do_create_pd(proc->task);
+ pd = do_create_pd(proc->leader);
return (void *)pd;
}
.priv_destroy = pd_destroy
};
- int preload_pd_init(void)
+ int lpd_init(void)
{
int ret;
return ret;
}
- void preload_pd_uninit(void)
+ void lpd_uninit(void)
{
sspt_proc_cb_set(NULL);
BuildRequires: perl
BuildRequires: python
-%ifarch %{arm}
- %if "%{?tizen_profile_name}" == "tv"
-BuildConflicts: vd_kernel-headers
+Provides: swap-modules
+
+%if "%{_repository}" == "emulator32" || "%{_repository}" == "emulator32-wayland"
+BuildRequires: emulator-kernel-devel
+ %define build_arch i386
+ %define kernel_path /usr/src/linux-kernel-build-3.14.25
+%else
+
+ %if "%{_repository}" == "target-TM1"
+BuildRequires: kernel-devel-3.10-sc7730
+ %define build_arch arm
+ %define kernel_path /boot/kernel/devel/kernel-devel-tizen_tm1
+ %else
+
+ %if "%{_repository}" == "target-circle"
+BuildRequires: kernel-devel-3.4-exynos3250
+ %define build_arch arm
+ %define kernel_path /boot/kernel/devel/kernel-devel-tizen_wc1
+ %else
+
+ %if "%{TIZEN_PRODUCT_TV}" == "1"
BuildRequires: tztv-hawk-kmodules-devel
%define build_arch arm
%define kernel_path /usr/include/kernel_header/debug
- %else
- %if "%{?tizen_profile_name}" == "mobile"
-ExcludeArch: %{arm}
- %else
- %if "%{?tizen_profile_name}" == "wearable"
-ExcludeArch: %{arm}
- %endif
- %endif
+ %else
+
+ExclusiveArch:
+ %endif
%endif
-%else #i386
- %define build_arch i386
-BuildRequires: emulator-kernel-devel
- %define kernel_path /usr/src/linux-kernel-build-3.14.25
+ %endif
%endif
-Provides: swap-modules
+
%description
Kernel modules for SWAP
install -m 666 parser/swap_message_parser.ko -t %{buildroot}/opt/swap/sdk
install -m 666 retprobe/swap_retprobe.ko -t %{buildroot}/opt/swap/sdk
install -m 666 webprobe/swap_webprobe.ko -t %{buildroot}/opt/swap/sdk
+ install -m 666 loader/swap_loader.ko -t %{buildroot}/opt/swap/sdk
install -m 666 preload/swap_preload.ko -t %{buildroot}/opt/swap/sdk
+ install -m 666 uihv/swap_uihv.ko -t %{buildroot}/opt/swap/sdk
install -m 666 fbiprobe/swap_fbiprobe.ko -t %{buildroot}/opt/swap/sdk
install -m 666 wsp/swap_wsp.ko -t %{buildroot}/opt/swap/sdk
install -m 666 nsp/swap_nsp.ko -t %{buildroot}/opt/swap/sdk
/opt/swap/sdk/swap_message_parser.ko
/opt/swap/sdk/swap_retprobe.ko
/opt/swap/sdk/swap_webprobe.ko
+ /opt/swap/sdk/swap_loader.ko
/opt/swap/sdk/swap_preload.ko
+ /opt/swap/sdk/swap_uihv.ko
/opt/swap/sdk/swap_fbiprobe.ko
/opt/swap/sdk/swap_wsp.ko
/opt/swap/sdk/swap_nsp.ko
#include <linux/limits.h>
#include <linux/list.h>
- #include <us_manager/sspt/ip.h>
+ #include <us_manager/sspt/sspt_ip.h>
#include "preload.h"
+ #include "preload_module.h"
#include "preload_control.h"
#include "preload_probe.h"
- #include "preload_module.h"
struct bin_desc {
struct list_head list;
if (unlikely(vma == NULL || vma->vm_file == NULL))
goto get_caller_dentry_fail;
- return vma->vm_file->f_dentry;
+ return vma->vm_file->f_path.dentry;
get_caller_dentry_fail:
/* Called only form handlers. If we're there, then it is instrumented. */
- enum preload_call_type preload_control_call_type_always_inst(void *caller)
+ enum preload_call_type pc_call_type_always_inst(void *caller)
{
if (__is_instrumented(caller))
return INTERNAL_CALL;
}
- enum preload_call_type preload_control_call_type(struct us_ip *ip, void *caller)
+ enum preload_call_type pc_call_type(struct sspt_ip *ip, void *caller)
{
if (__is_instrumented(caller))
return INTERNAL_CALL;
return NOT_INSTRUMENTED;
}
- int preload_control_add_instrumented_binary(char *filename)
+ int pc_add_instrumented_binary(char *filename)
{
struct dentry *dentry = get_dentry(filename);
int res = 0;
return res > 0 ? 0 : res;
}
- int preload_control_clean_instrumented_bins(void)
+ int pc_clean_instrumented_bins(void)
{
__free_binaries(&target);
return 0;
}
- int preload_control_add_ignored_binary(char *filename)
+ int pc_add_ignored_binary(char *filename)
{
struct dentry *dentry = get_dentry(filename);
int res = 0;
return res > 0 ? 0 : res;
}
- int preload_control_clean_ignored_bins(void)
+ int pc_clean_ignored_bins(void)
{
__free_binaries(&ignored);
return 0;
}
- unsigned int preload_control_get_target_names(char ***filenames_p)
+ unsigned int pc_get_target_names(char ***filenames_p)
{
return __get_names(&target, filenames_p);
}
- void preload_control_release_target_names(char ***filenames_p)
+ void pc_release_target_names(char ***filenames_p)
{
kfree(*filenames_p);
}
- unsigned int preload_control_get_ignored_names(char ***filenames_p)
+ unsigned int pc_get_ignored_names(char ***filenames_p)
{
return __get_names(&ignored, filenames_p);
}
- void preload_control_release_ignored_names(char ***filenames_p)
+ void pc_release_ignored_names(char ***filenames_p)
{
kfree(*filenames_p);
}
- bool preload_control_check_dentry_is_ignored(struct dentry *dentry)
+ bool pc_check_dentry_is_ignored(struct dentry *dentry)
{
struct bin_desc *p;
bool ret = false;
return ret;
}
- int preload_control_init(void)
+ int pc_init(void)
{
return 0;
}
- void preload_control_exit(void)
+ void pc_exit(void)
{
__free_binaries(&target);
__free_binaries(&ignored);
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/list.h>
+ #include <kprobe/swap_ktd.h>
#include <us_manager/us_slot_manager.h>
static LIST_HEAD(proc_probes_list);
write_unlock(&sspt_proc_rwlock);
}
+ struct ktd_proc {
+ struct sspt_proc *proc;
+ spinlock_t lock;
+ };
- /**
- * @brief Create sspt_proc struct
- *
- * @param task Pointer to the task_struct struct
- * @param priv Private data
- * @return Pointer to the created sspt_proc struct
- */
- struct sspt_proc *sspt_proc_create(struct task_struct *task)
+ static void ktd_init(struct task_struct *task, void *data)
+ {
+ struct ktd_proc *kproc = (struct ktd_proc *)data;
+
+ kproc->proc = NULL;
+ spin_lock_init(&kproc->lock);
+ }
+
+ static void ktd_exit(struct task_struct *task, void *data)
+ {
+ struct ktd_proc *kproc = (struct ktd_proc *)data;
+
+ WARN_ON(kproc->proc);
+ }
+
+ struct ktask_data ktd = {
+ .init = ktd_init,
+ .exit = ktd_exit,
+ .size = sizeof(struct ktd_proc),
+ };
+
+ static struct ktd_proc *kproc_by_task(struct task_struct *task)
+ {
+ return (struct ktd_proc *)swap_ktd(&ktd, task);
+ }
+
+ int sspt_proc_init(void)
+ {
+ return swap_ktd_reg(&ktd);
+ }
+
+ void sspt_proc_uninit(void)
{
- struct sspt_proc *proc = kzalloc(sizeof(*proc), GFP_ATOMIC);
+ swap_ktd_unreg(&ktd);
+ }
+
+ void sspt_change_leader(struct task_struct *prev, struct task_struct *next)
+ {
+ struct ktd_proc *prev_kproc;
+
+ prev_kproc = kproc_by_task(prev);
+ spin_lock(&prev_kproc->lock);
+ if (prev_kproc->proc) {
+ struct ktd_proc *next_kproc;
+
+ next_kproc = kproc_by_task(next);
+ get_task_struct(next);
+
+ /* Change the keeper sspt_proc */
+ BUG_ON(next_kproc->proc);
+
+ spin_lock(&next_kproc->lock);
+ next_kproc->proc = prev_kproc->proc;
+ prev_kproc->proc = NULL;
+ spin_unlock(&next_kproc->lock);
+
+ /* Set new the task leader to sspt_proc */
+ next_kproc->proc->leader = next;
+
+ put_task_struct(prev);
+ }
+ spin_unlock(&prev_kproc->lock);
+ }
+
+ static void sspt_reset_proc(struct task_struct *task)
+ {
+ struct ktd_proc *kproc;
+
+ kproc = kproc_by_task(task->group_leader);
+ spin_lock(&kproc->lock);
+ kproc->proc = NULL;
+ spin_unlock(&kproc->lock);
+ }
+
+
+
+
+
+ static struct sspt_proc *sspt_proc_create(struct task_struct *leader)
+ {
+ struct sspt_proc *proc = kzalloc(sizeof(*proc), GFP_KERNEL);
if (proc) {
proc->feature = sspt_create_feature();
}
INIT_LIST_HEAD(&proc->list);
- proc->tgid = task->tgid;
- proc->task = task->group_leader;
- proc->sm = create_sm_us(task);
- INIT_LIST_HEAD(&proc->file_list);
- rwlock_init(&proc->filter_lock);
- INIT_LIST_HEAD(&proc->filter_list);
+ INIT_LIST_HEAD(&proc->files.head);
+ init_rwsem(&proc->files.sem);
+ proc->tgid = leader->tgid;
+ proc->leader = leader;
+ /* FIXME: change the task leader */
+ proc->sm = create_sm_us(leader);
+ mutex_init(&proc->filters.mtx);
+ INIT_LIST_HEAD(&proc->filters.head);
atomic_set(&proc->usage, 1);
- get_task_struct(proc->task);
+ get_task_struct(proc->leader);
- /* add to list */
- list_add(&proc->list, &proc_probes_list);
+ proc->suspect.after_exec = 1;
+ proc->suspect.after_fork = 0;
}
return proc;
}
+ static void sspt_proc_free(struct sspt_proc *proc)
+ {
+ put_task_struct(proc->leader);
+ free_sm_us(proc->sm);
+ sspt_destroy_feature(proc->feature);
+ kfree(proc);
+ }
+
/**
* @brief Remove sspt_proc struct
*
sspt_proc_del_all_filters(proc);
- list_for_each_entry_safe(file, n, &proc->file_list, list) {
+ down_write(&proc->files.sem);
+ list_for_each_entry_safe(file, n, &proc->files.head, list) {
list_del(&file->list);
sspt_file_free(file);
}
+ up_write(&proc->files.sem);
sspt_destroy_feature(proc->feature);
free_sm_us(proc->sm);
+ sspt_reset_proc(proc->leader);
sspt_proc_put(proc);
}
proc->__task = NULL;
}
- put_task_struct(proc->task);
+ WARN_ON(kproc_by_task(proc->leader)->proc);
+
+ put_task_struct(proc->leader);
kfree(proc);
}
}
+ EXPORT_SYMBOL_GPL(sspt_proc_put);
+
+ struct sspt_proc *sspt_proc_by_task(struct task_struct *task)
+ {
+ return kproc_by_task(task->group_leader)->proc;
+ }
+ EXPORT_SYMBOL_GPL(sspt_proc_by_task);
struct sspt_proc *sspt_proc_get_by_task(struct task_struct *task)
{
+ struct ktd_proc *kproc = kproc_by_task(task->group_leader);
struct sspt_proc *proc;
- sspt_proc_read_lock();
- proc = sspt_proc_get_by_task_no_lock(task);
- sspt_proc_read_unlock();
+ spin_lock(&kproc->lock);
+ proc = kproc->proc;
+ if (proc)
+ sspt_proc_get(proc);
+ spin_unlock(&kproc->lock);
return proc;
}
EXPORT_SYMBOL_GPL(sspt_proc_get_by_task);
/**
- * @brief Get sspt_proc by task
- *
- * @param task Pointer on the task_struct struct
- * @return Pointer on the sspt_proc struct
- */
- struct sspt_proc *sspt_proc_get_by_task_no_lock(struct task_struct *task)
- {
- struct sspt_proc *proc, *tmp;
-
- list_for_each_entry_safe(proc, tmp, &proc_probes_list, list) {
- if (proc->tgid == task->tgid)
- return proc;
- }
-
- return NULL;
- }
- EXPORT_SYMBOL_GPL(sspt_proc_get_by_task_no_lock);
-
- /**
* @brief Call func() on each proc (no lock)
*
* @param func Callback
*/
struct sspt_proc *sspt_proc_get_by_task_or_new(struct task_struct *task)
{
+ static DEFINE_MUTEX(local_mutex);
+ struct ktd_proc *kproc;
struct sspt_proc *proc;
+ struct task_struct *leader = task->group_leader;
- sspt_proc_write_lock();
- proc = sspt_proc_get_by_task_no_lock(task);
- if (proc == NULL)
- proc = sspt_proc_create(task);
- sspt_proc_write_unlock();
+ kproc = kproc_by_task(leader);
+ if (kproc->proc)
+ goto out;
- return proc;
+ proc = sspt_proc_create(leader);
+
+ spin_lock(&kproc->lock);
+ if (kproc->proc == NULL) {
+ sspt_proc_get(proc);
+ kproc->proc = proc;
+ proc = NULL;
+
+ sspt_proc_write_lock();
+ list_add(&kproc->proc->list, &proc_probes_list);
+ sspt_proc_write_unlock();
+ }
+ spin_unlock(&kproc->lock);
+
+ if (proc)
+ sspt_proc_free(proc);
+
+ out:
+ return kproc->proc;
}
/**
- * @brief Free all sspt_proc
+ * @brief Check sspt_proc on empty
*
* @return Pointer on the sspt_proc struct
*/
- void sspt_proc_free_all(void)
+ void sspt_proc_check_empty(void)
{
- struct sspt_proc *proc, *n;
-
- list_for_each_entry_safe(proc, n, &proc_probes_list, list) {
- list_del(&proc->list);
- sspt_proc_cleanup(proc);
- }
+ WARN_ON(!list_empty(&proc_probes_list));
}
static void sspt_proc_add_file(struct sspt_proc *proc, struct sspt_file *file)
{
- list_add(&file->list, &proc->file_list);
+ down_write(&proc->files.sem);
+ list_add(&file->list, &proc->files.head);
file->proc = proc;
+ up_write(&proc->files.sem);
}
/**
{
struct sspt_file *file;
- list_for_each_entry(file, &proc->file_list, list) {
+ down_read(&proc->files.sem);
+ list_for_each_entry(file, &proc->files.head, list) {
if (dentry == file->dentry)
- return file;
+ goto unlock;
}
+ file = NULL;
- return NULL;
+ unlock:
+ up_read(&proc->files.sem);
+
+ return file;
}
/**
*/
void sspt_proc_install_page(struct sspt_proc *proc, unsigned long page_addr)
{
- struct mm_struct *mm = proc->task->mm;
+ struct mm_struct *mm = proc->leader->mm;
struct vm_area_struct *vma;
vma = find_vma_intersection(mm, page_addr, page_addr + 1);
if (vma && check_vma(vma)) {
- struct dentry *dentry = vma->vm_file->f_dentry;
+ struct dentry *dentry = vma->vm_file->f_path.dentry;
struct sspt_file *file = sspt_proc_find_file(proc, dentry);
if (file) {
struct sspt_page *page;
void sspt_proc_install(struct sspt_proc *proc)
{
struct vm_area_struct *vma;
- struct mm_struct *mm = proc->task->mm;
+ struct mm_struct *mm = proc->leader->mm;
proc->first_install = 1;
for (vma = mm->mmap; vma; vma = vma->vm_next) {
if (check_vma(vma)) {
- struct dentry *dentry = vma->vm_file->f_dentry;
+ struct dentry *dentry = vma->vm_file->f_path.dentry;
struct sspt_file *file =
sspt_proc_find_file(proc, dentry);
if (file) {
int err = 0;
struct sspt_file *file;
- list_for_each_entry_rcu(file, &proc->file_list, list) {
+ down_read(&proc->files.sem);
+ list_for_each_entry(file, &proc->files.head, list) {
err = sspt_file_uninstall(file, task, flag);
if (err != 0) {
printk(KERN_INFO "ERROR sspt_proc_uninstall: err=%d\n",
err);
- return err;
+ break;
}
}
+ up_read(&proc->files.sem);
return err;
}
struct sspt_file *file, *n;
unsigned long end = start + len;
- list_for_each_entry_safe(file, n, &proc->file_list, list) {
+ down_write(&proc->files.sem);
+ list_for_each_entry_safe(file, n, &proc->files.head, list) {
if (intersection(file->vm_start, file->vm_end, start, end)) {
ret = 1;
list_move(&file->list, head);
}
}
+ up_write(&proc->files.sem);
return ret;
}
*/
void sspt_proc_insert_files(struct sspt_proc *proc, struct list_head *head)
{
- list_splice(head, &proc->file_list);
+ down_write(&proc->files.sem);
+ list_splice(head, &proc->files.head);
+ up_write(&proc->files.sem);
}
/**
f = sspt_filter_create(proc, pfg);
if (f)
- list_add(&f->list, &proc->filter_list);
+ list_add(&f->list, &proc->filters.head);
}
/**
{
struct sspt_filter *fl, *tmp;
- write_lock(&proc->filter_lock);
- list_for_each_entry_safe(fl, tmp, &proc->filter_list, list) {
+ mutex_lock(&proc->filters.mtx);
+ list_for_each_entry_safe(fl, tmp, &proc->filters.head, list) {
if (fl->pfg == pfg) {
list_del(&fl->list);
sspt_filter_free(fl);
}
}
- write_unlock(&proc->filter_lock);
+ mutex_unlock(&proc->filters.mtx);
}
/**
{
struct sspt_filter *fl, *tmp;
- write_lock(&proc->filter_lock);
- list_for_each_entry_safe(fl, tmp, &proc->filter_list, list) {
+ mutex_lock(&proc->filters.mtx);
+ list_for_each_entry_safe(fl, tmp, &proc->filters.head, list) {
list_del(&fl->list);
sspt_filter_free(fl);
}
- write_unlock(&proc->filter_lock);
+ mutex_unlock(&proc->filters.mtx);
}
/**
{
struct sspt_filter *fl;
- list_for_each_entry(fl, &proc->filter_list, list)
+ list_for_each_entry(fl, &proc->filters.head, list)
if (fl->pfg == pfg)
return false;
{
struct sspt_filter *fl;
- list_for_each_entry(fl, &proc->filter_list, list)
+ list_for_each_entry(fl, &proc->filters.head, list)
func(fl, data);
}
void sspt_proc_on_each_ip(struct sspt_proc *proc,
- void (*func)(struct us_ip *, void *), void *data)
+ void (*func)(struct sspt_ip *, void *), void *data)
{
struct sspt_file *file;
- list_for_each_entry(file, &proc->file_list, list)
+ down_read(&proc->files.sem);
+ list_for_each_entry(file, &proc->files.head, list)
sspt_file_on_each_ip(file, func, data);
+ up_read(&proc->files.sem);
}
static void is_send_event(struct sspt_filter *f, void *data)
#include <us_manager/us_manager.h>
- #include <us_manager/sspt/ip.h>
+ #include <us_manager/sspt/sspt_ip.h>
#include <us_manager/probes/register_probes.h>
#include <us_manager/sspt/sspt.h>
#include <uprobe/swap_uprobes.h>
{
}
- static struct uprobe *webprobe_get_uprobe(struct us_ip *ip)
+ static struct uprobe *webprobe_get_uprobe(struct sspt_ip *ip)
{
return &ip->retprobe.up;
}
- static int webprobe_register_probe(struct us_ip *ip)
+ static int webprobe_register_probe(struct sspt_ip *ip)
{
return swap_register_uretprobe(&ip->retprobe);
}
- static void webprobe_unregister_probe(struct us_ip *ip, int disarm)
+ static void webprobe_unregister_probe(struct sspt_ip *ip, int disarm)
{
if (ip->orig_addr == inspserver_addr_local)
web_func_inst_remove(INSPSERVER_START);
struct pt_regs *regs)
{
struct uretprobe *rp = ri->rp;
- struct us_ip *ip;
+ struct sspt_ip *ip;
unsigned long vaddr, page_vaddr;
struct vm_area_struct *vma;
if (rp == NULL)
return 0;
- ip = container_of(rp, struct us_ip, retprobe);
+ ip = container_of(rp, struct sspt_ip, retprobe);
vaddr = (unsigned long)ip->orig_addr;
page_vaddr = vaddr & PAGE_MASK;
vma = find_vma_intersection(current->mm, page_vaddr, page_vaddr + 1);
if (vma && check_vma(vma)) {
unsigned long addr = vaddr - vma->vm_start;
- struct dentry *d = vma->vm_file->f_dentry;
+ struct dentry *d = vma->vm_file->f_path.dentry;
if (addr == web_prof_addr(WILL_EXECUTE) &&
d == web_prof_lib_dentry()) {
static int web_ret_handler(struct uretprobe_instance *ri, struct pt_regs *regs)
{
struct uretprobe *rp = ri->rp;
- struct us_ip *ip;
+ struct sspt_ip *ip;
unsigned long vaddr, page_vaddr;
struct vm_area_struct *vma;
if (rp == NULL)
return 0;
- ip = container_of(rp, struct us_ip, retprobe);
+ ip = container_of(rp, struct sspt_ip, retprobe);
vaddr = (unsigned long)ip->orig_addr;
page_vaddr = vaddr & PAGE_MASK;
vma = find_vma_intersection(current->mm, page_vaddr, page_vaddr + 1);
if (vma && check_vma(vma)) {
unsigned long addr = vaddr - vma->vm_start;
- struct dentry *d = vma->vm_file->f_dentry;
+ struct dentry *d = vma->vm_file->f_path.dentry;
if (addr == web_prof_addr(INSPSERVER_START) &&
d == web_prof_lib_dentry()) {
return 0;
}
- static void webprobe_init(struct us_ip *ip)
+ static void webprobe_init(struct sspt_ip *ip)
{
ip->retprobe.entry_handler = web_entry_handler;
ip->retprobe.handler = web_ret_handler;
ip->retprobe.maxactive = 0;
}
- static void webprobe_uninit(struct us_ip *ip)
+ static void webprobe_uninit(struct sspt_ip *ip)
{
webprobe_cleanup(&ip->desc->info);
}