From 64e46dabcc1f3b05067998febfa39eef1be1152d Mon Sep 17 00:00:00 2001 From: Anatolii Nikulin Date: Tue, 25 Aug 2015 15:52:36 +0300 Subject: [PATCH] [FIX] prevent issues fix 42 issues from prevent: NULL_RETURNS UNINIT REVERSE_INULL RESOURCE_LEAK MISSING_BREAK DEADCODE DC.SECURE_CODING_SPRINTF FORWARD_NULL DC.SECURE_CODING_STRCPY OVERFLOW_BEFORE_WIDEN BAD_SIZEOF Change-Id: I1e7bc4b6e73e8262ee6fa23238d86a62510cb4e5 Signed-off-by: Anatolii Nikulin --- fbiprobe/fbiprobe.c | 15 +++++++++--- kprobe/swap_kprobes_deps.c | 7 +++++- kprobe/swap_slots.c | 6 +++++ ks_features/file_ops.c | 2 +- ks_features/ks_features.c | 2 +- ks_manager/ks_manager.c | 3 +++ preload/preload_control.c | 3 +++ preload/preload_debugfs.c | 11 +++++---- preload/preload_pd.c | 38 ++++++++++++++++------------- preload/preload_threads.c | 19 +++++++++++++-- sampler/sampler_hrtimer.c | 3 ++- uprobe/arch/arm/swap-asm/swap_uprobes.h | 4 ++++ us_manager/debugfs_us_manager.c | 2 +- us_manager/img/img_file.c | 3 +++ us_manager/pf/pf_group.c | 12 +++++++--- us_manager/sspt/sspt.h | 3 ++- us_manager/sspt/sspt_feature.c | 5 ++-- us_manager/sspt/sspt_file.c | 42 ++++++++++++++++++++------------- us_manager/sspt/sspt_proc.c | 3 ++- us_manager/us_slot_manager.c | 4 ++++ webprobe/webprobe_debugfs.c | 4 ++-- writer/debugfs_writer.c | 4 +++- writer/swap_msg.c | 4 ---- 23 files changed, 136 insertions(+), 63 deletions(-) diff --git a/fbiprobe/fbiprobe.c b/fbiprobe/fbiprobe.c index d507502..bd51162 100644 --- a/fbiprobe/fbiprobe.c +++ b/fbiprobe/fbiprobe.c @@ -341,12 +341,15 @@ int fbi_probe_copy(struct probe_info *dest, const struct probe_info *source) struct fbi_step *steps_source; struct fbi_step *steps_dest = NULL; uint8_t i; - + int ret = 0; memcpy(dest, source, sizeof(*source)); vars_size = source->fbi_i.var_count * sizeof(*source->fbi_i.vars); vars = kmalloc(vars_size, GFP_KERNEL); + if (vars == NULL) + return -ENOMEM; + memcpy(vars, source->fbi_i.vars, vars_size); for (i = 0; i != source->fbi_i.var_count; i++) { @@ -359,7 +362,8 @@ int fbi_probe_copy(struct probe_info *dest, const struct probe_info *source) steps_dest = kmalloc(steps_size, GFP_KERNEL); if (steps_dest == NULL) { print_err("can not alloc data\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err; } memcpy(steps_dest, steps_source, steps_size); @@ -369,7 +373,12 @@ int fbi_probe_copy(struct probe_info *dest, const struct probe_info *source) dest->fbi_i.vars = vars; - return 0; + return ret; +err: + while (--i >= 0) + kfree(vars[i].steps); + kfree(vars); + return ret; } /* Register */ diff --git a/kprobe/swap_kprobes_deps.c b/kprobe/swap_kprobes_deps.c index d5179a6..5c4bef4 100644 --- a/kprobe/swap_kprobes_deps.c +++ b/kprobe/swap_kprobes_deps.c @@ -273,7 +273,12 @@ static inline int swap_in_gate_area(struct task_struct *task, { #ifdef __HAVE_ARCH_GATE_AREA #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) - struct mm_struct *mm = task->mm; + struct mm_struct *mm; + + if (task == NULL) + return 0; + + mm = task->mm; IMP_MOD_DEP_WRAPPER(in_gate_area, mm, addr) #else /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */ IMP_MOD_DEP_WRAPPER(in_gate_area, task, addr) diff --git a/kprobe/swap_slots.c b/kprobe/swap_slots.c index c6406a0..f0aea18 100644 --- a/kprobe/swap_slots.c +++ b/kprobe/swap_slots.c @@ -97,6 +97,12 @@ static void chunk_init(struct chunk *chunk, chunk->index = kmalloc(sizeof(*chunk->index)*chunk->count_available, GFP_ATOMIC); + + if (chunk->index == NULL) { + printk(KERN_ERR "%s: failed to allocate memory\n", __FUNCTION__); + return; + } + p = chunk->index; for (i = 0; i != chunk->count_available; ++p) *p = ++i; diff --git a/ks_features/file_ops.c b/ks_features/file_ops.c index e0fd724..8845a74 100644 --- a/ks_features/file_ops.c +++ b/ks_features/file_ops.c @@ -660,7 +660,7 @@ static char *__fops_dpath(struct dentry *dentry, char *buf, int buflen) if (IS_ERR_OR_NULL(filename)) { printk(FOPS_PREFIX "dentry_path_raw FAILED: %ld\n", PTR_ERR(filename)); - strcpy(buf, NA); + strncpy(buf, NA, buflen); filename = buf; } diff --git a/ks_features/ks_features.c b/ks_features/ks_features.c index 3993cb8..f462e7a 100644 --- a/ks_features/ks_features.c +++ b/ks_features/ks_features.c @@ -300,7 +300,7 @@ static int unregister_multiple_syscalls(size_t *id_p, size_t cnt) --cnt; - rpp = kmalloc(GFP_KERNEL, sizeof(&(((struct ks_probe *) 0)->rp)) * cnt); + rpp = kmalloc(GFP_KERNEL, sizeof(*rpp) * cnt); if (rpp == NULL) { for (; cnt != end; --cnt) { ret = unregister_syscall(id_p[cnt]); diff --git a/ks_manager/ks_manager.c b/ks_manager/ks_manager.c index fc1c9e9..a8abc65 100644 --- a/ks_manager/ks_manager.c +++ b/ks_manager/ks_manager.c @@ -40,6 +40,9 @@ static struct probe *create_probe(unsigned long addr, void *pre_handler, { struct probe *p = kzalloc(sizeof(*p), GFP_KERNEL); + if (p == NULL) + return NULL; + p->p.jp.kp.addr = p->p.rp.kp.addr = (void *)addr; p->p.jp.pre_entry = pre_handler; p->p.jp.entry = jp_handler; diff --git a/preload/preload_control.c b/preload/preload_control.c index 5a79c84..2f5aef8 100644 --- a/preload/preload_control.c +++ b/preload/preload_control.c @@ -257,6 +257,9 @@ unsigned int preload_control_get_bin_names(char ***filenames_p) int i; unsigned int ret = 0; + if (target_binaries_cnt == 0) + return 0; + __target_binaries_lock(); *filenames_p = kmalloc(sizeof(**filenames_p) * target_binaries_cnt, diff --git a/preload/preload_debugfs.c b/preload/preload_debugfs.c index 8af94bb..9e412c9 100644 --- a/preload/preload_debugfs.c +++ b/preload/preload_debugfs.c @@ -116,7 +116,7 @@ struct dentry *debugfs_create_ptr(const char *name, mode_t mode, */ static ssize_t loader_path_write(struct file *file, const char __user *buf, - size_t len, loff_t *ppos) + size_t len, loff_t *ppos) { ssize_t ret; char *path; @@ -128,20 +128,21 @@ static ssize_t loader_path_write(struct file *file, const char __user *buf, path = kmalloc(len, GFP_KERNEL); if (path == NULL) { - ret = -ENOMEM; - goto out; + return -ENOMEM; } if (copy_from_user(path, buf, len)) { ret = -EINVAL; - goto out; + goto err; } path[len - 1] = '\0'; set_loader_file(path); ret = len; -out: + return ret; +err: + kfree(path); return ret; } diff --git a/preload/preload_pd.c b/preload/preload_pd.c index 628f434..b75dde2 100644 --- a/preload/preload_pd.c +++ b/preload/preload_pd.c @@ -235,13 +235,18 @@ char __user *preload_pd_get_path(struct process_data *pd) /* This function should be called only for current */ struct task_struct *task = current; - unsigned long page = __get_data_page(pd); + unsigned long page = 0; int ret; - if (pd == NULL || page == 0) + if (pd == NULL) + return NULL; + + page = __get_data_page(pd); + + if (page == 0) return NULL; - if (pd->is_mapped == 1) + if (pd->is_mapped == 1) return __get_path(pd); ret = preload_patcher_write_string((void *)page, handlers_info->path, @@ -249,16 +254,16 @@ char __user *preload_pd_get_path(struct process_data *pd) task); if (ret <= 0) { printk(KERN_ERR PRELOAD_PREFIX "Cannot copy string to user!\n"); - goto get_path_failed; + goto get_path_failed; } - pd->is_mapped = 1; + pd->is_mapped = 1; return __get_path(pd); get_path_failed: - return NULL; + return NULL; } @@ -343,25 +348,21 @@ long preload_pd_get_refs(struct process_data *pd) return __get_refcount(pd); } -int preload_pd_create_pd(void** target_place, struct task_struct *task) +int preload_pd_create_pd(void **target_place, struct task_struct *task) { - struct process_data *pd; - unsigned long page = 0; + struct process_data *pd; + unsigned long page = 0; unsigned long base; struct dentry *dentry; - int ret; + int ret = 0; ret = __pd_create_on_demand(); if (ret) - goto create_pd_exit; + return ret; pd = kzalloc(sizeof(*pd), GFP_ATOMIC); - if (pd == NULL) { - ret = -ENOMEM; - goto create_pd_exit; - } - - ret = 0; + if (pd == NULL) + return -ENOMEM; /* 1. check if loader is already mapped */ dentry = preload_debugfs_get_loader_dentry(); @@ -399,7 +400,10 @@ int preload_pd_create_pd(void** target_place, struct task_struct *task) *target_place = pd; + return ret; + create_pd_exit: + kfree(pd); return ret; } diff --git a/preload/preload_threads.c b/preload/preload_threads.c index 360e354..7c881d4 100644 --- a/preload/preload_threads.c +++ b/preload/preload_threads.c @@ -57,13 +57,25 @@ static inline struct preload_td *get_preload_td(struct task_struct *task) unsigned long get_preload_flags(struct task_struct *task) { - return get_preload_td(task)->flags; + struct preload_td *td = get_preload_td(task); + + if (td == NULL) + return 0; + + return td->flags; } void set_preload_flags(struct task_struct *task, unsigned long flags) { - get_preload_td(task)->flags = flags; + struct preload_td *td = get_preload_td(task); + + if (td == NULL) { + printk(KERN_ERR "%s: invalid arguments\n", __FUNCTION__); + return; + } + + td->flags = flags; } @@ -171,6 +183,9 @@ static inline struct thread_slot *__get_task_slot(struct task_struct *task) { struct preload_td *td = get_preload_td(task); + if (td == NULL) + return NULL; + return list_empty(&td->slots) ? NULL : list_last_entry(&td->slots, struct thread_slot, list); } diff --git a/sampler/sampler_hrtimer.c b/sampler/sampler_hrtimer.c index 481791e..c0e669e 100644 --- a/sampler/sampler_hrtimer.c +++ b/sampler/sampler_hrtimer.c @@ -116,5 +116,6 @@ void sampler_timers_stop(int cpu) */ void sampler_timers_set_quantum(unsigned int timer_quantum) { - sampler_timer_quantum = timer_quantum * 1000 * 1000; + u64 tmp = (u64)timer_quantum; + sampler_timer_quantum = tmp * 1000 * 1000; } diff --git a/uprobe/arch/arm/swap-asm/swap_uprobes.h b/uprobe/arch/arm/swap-asm/swap_uprobes.h index 51342af..885f227 100644 --- a/uprobe/arch/arm/swap-asm/swap_uprobes.h +++ b/uprobe/arch/arm/swap-asm/swap_uprobes.h @@ -119,12 +119,16 @@ static inline void swap_put_uarg(struct pt_regs *regs, unsigned long n, switch (n) { case 0: regs->ARM_r0 = val; + break; case 1: regs->ARM_r1 = val; + break; case 2: regs->ARM_r2 = val; + break; case 3: regs->ARM_r3 = val; + break; } ptr = (u32 *)regs->ARM_sp + n - 4; diff --git a/us_manager/debugfs_us_manager.c b/us_manager/debugfs_us_manager.c index 88cb17a..727e4e5 100644 --- a/us_manager/debugfs_us_manager.c +++ b/us_manager/debugfs_us_manager.c @@ -32,7 +32,7 @@ static void on_each_proc_callback(struct sspt_proc *proc, void *data) if (!sspt_proc_is_send_event(proc)) return; - sprintf(pid_str, "%d", proc->tgid); + snprintf(pid_str, sizeof(pid_str), "%d", proc->tgid); len = strlen(pid_str); diff --git a/us_manager/img/img_file.c b/us_manager/img/img_file.c index b21ad73..c670ca7 100644 --- a/us_manager/img/img_file.c +++ b/us_manager/img/img_file.c @@ -110,6 +110,9 @@ int img_file_add_ip(struct img_file *file, unsigned long addr, } ip = create_img_ip(addr, probe_i); + if (ip == NULL) + return -ENOMEM; + img_add_ip_by_list(file, ip); return 0; diff --git a/us_manager/pf/pf_group.c b/us_manager/pf/pf_group.c index f544728..5fb56a3 100644 --- a/us_manager/pf/pf_group.c +++ b/us_manager/pf/pf_group.c @@ -61,6 +61,9 @@ static struct pl_struct *create_pl_struct(struct sspt_proc *proc) { struct pl_struct *pls = kmalloc(sizeof(*pls), GFP_KERNEL); + if (pls == NULL) + return NULL; + INIT_LIST_HEAD(&pls->list); pls->proc = proc; @@ -526,7 +529,8 @@ void check_task_and_install(struct task_struct *task) case PIF_FIRST: case PIF_ADD_PFG: proc = sspt_proc_get_by_task(task); - first_install(task, proc); + if (proc) + first_install(task, proc); break; case PIF_NONE: @@ -552,12 +556,14 @@ void call_page_fault(struct task_struct *task, unsigned long page_addr) case PIF_FIRST: case PIF_ADD_PFG: proc = sspt_proc_get_by_task(task); - first_install(task, proc); + if (proc) + first_install(task, proc); break; case PIF_SECOND: proc = sspt_proc_get_by_task(task); - subsequent_install(task, proc, page_addr); + if (proc) + subsequent_install(task, proc, page_addr); break; case PIF_NONE: diff --git a/us_manager/sspt/sspt.h b/us_manager/sspt/sspt.h index 3199ae7..f3e40e2 100644 --- a/us_manager/sspt/sspt.h +++ b/us_manager/sspt/sspt.h @@ -89,7 +89,8 @@ static inline int sspt_unregister_usprobe(struct task_struct *task, break; case US_DISARM: up = probe_info_get_uprobe(ip->info, ip); - disarm_uprobe(&up->kp, task); + if (up) + disarm_uprobe(&up->kp, task); break; case US_UNINSTALL: probe_info_unregister(ip->info, ip, 0); diff --git a/us_manager/sspt/sspt_feature.c b/us_manager/sspt/sspt_feature.c index 4be4772..bc2c84d 100644 --- a/us_manager/sspt/sspt_feature.c +++ b/us_manager/sspt/sspt_feature.c @@ -92,9 +92,8 @@ struct sspt_feature *sspt_create_feature(void) spin_lock_irqsave(&feature_img_lock, flags); list_for_each_entry(fi, &feature_img_list, list) { fd = create_feature_data(fi); - - /* add to list */ - list_add(&fd->list, &f->feature_list); + if (fd) /* add to list */ + list_add(&fd->list, &f->feature_list); } spin_unlock_irqrestore(&feature_img_lock, flags); } diff --git a/us_manager/sspt/sspt_file.c b/us_manager/sspt/sspt_file.c index 8b88ff0..917335a 100644 --- a/us_manager/sspt/sspt_file.c +++ b/us_manager/sspt/sspt_file.c @@ -50,29 +50,37 @@ static int calculation_hash_bits(int cnt) */ struct sspt_file *sspt_file_create(struct dentry *dentry, int page_cnt) { + int i, table_size; struct sspt_file *obj = kmalloc(sizeof(*obj), GFP_ATOMIC); - if (obj) { - int i, table_size; - INIT_LIST_HEAD(&obj->list); - obj->proc = NULL; - obj->dentry = dentry; - obj->loaded = 0; - obj->vm_start = 0; - obj->vm_end = 0; + if (obj == NULL) + return NULL; + + INIT_LIST_HEAD(&obj->list); + obj->proc = NULL; + obj->dentry = dentry; + obj->loaded = 0; + obj->vm_start = 0; + obj->vm_end = 0; - obj->page_probes_hash_bits = calculation_hash_bits(page_cnt); - table_size = (1 << obj->page_probes_hash_bits); + obj->page_probes_hash_bits = calculation_hash_bits(page_cnt); + table_size = (1 << obj->page_probes_hash_bits); - obj->page_probes_table = + obj->page_probes_table = kmalloc(sizeof(*obj->page_probes_table)*table_size, GFP_ATOMIC); - for (i = 0; i < table_size; ++i) - INIT_HLIST_HEAD(&obj->page_probes_table[i]); - } + if (obj->page_probes_table == NULL) + goto err; + + for (i = 0; i < table_size; ++i) + INIT_HLIST_HEAD(&obj->page_probes_table[i]); return obj; + +err: + kfree(obj); + return NULL; } /** @@ -134,7 +142,8 @@ static struct sspt_page *sspt_find_page_or_new(struct sspt_file *file, if (page == NULL) { page = sspt_page_create(offset); - sspt_add_page(file, page); + if (page) + sspt_add_page(file, page); } return page; @@ -185,7 +194,8 @@ void sspt_file_add_ip(struct sspt_file *file, unsigned long offset, /* FIXME: delete ip */ struct us_ip *ip = create_ip(offset, probe_i, page); - sspt_add_ip(page, ip); + if (page && ip) + sspt_add_ip(page, ip); } /** diff --git a/us_manager/sspt/sspt_proc.c b/us_manager/sspt/sspt_proc.c index 71744a8..88ea025 100644 --- a/us_manager/sspt/sspt_proc.c +++ b/us_manager/sspt/sspt_proc.c @@ -240,7 +240,8 @@ struct sspt_file *sspt_proc_find_file_or_new(struct sspt_proc *proc, file = sspt_proc_find_file(proc, dentry); if (file == NULL) { file = sspt_file_create(dentry, 10); - sspt_proc_add_file(proc, file); + if (file) + sspt_proc_add_file(proc, file); } return file; diff --git a/us_manager/us_slot_manager.c b/us_manager/us_slot_manager.c index 5970514..536d349 100644 --- a/us_manager/us_slot_manager.c +++ b/us_manager/us_slot_manager.c @@ -77,6 +77,10 @@ static void sm_free_us(struct slot_manager *sm, void *ptr) struct slot_manager *create_sm_us(struct task_struct *task) { struct slot_manager *sm = kmalloc(sizeof(*sm), GFP_ATOMIC); + + if (sm == NULL) + return NULL; + sm->slot_size = UPROBES_TRAMP_LEN; sm->alloc = sm_alloc_us; sm->free = sm_free_us; diff --git a/webprobe/webprobe_debugfs.c b/webprobe/webprobe_debugfs.c index d72c4d5..f395ea4 100644 --- a/webprobe/webprobe_debugfs.c +++ b/webprobe/webprobe_debugfs.c @@ -97,7 +97,7 @@ static const struct file_operations fops_enabled = { static ssize_t write_app_info(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { - int ret; + int ret = 0; char *buf, *path, *id; int n; @@ -135,7 +135,7 @@ static ssize_t write_app_info(struct file *file, const char __user *user_buf, } web_prof_data_set(path, id); - sprintf(app_info, "%s\n", buf); + snprintf(app_info, sizeof(app_info), "%s\n", buf); free_app_info: kfree(id); diff --git a/writer/debugfs_writer.c b/writer/debugfs_writer.c index 0eb7100..e797abb 100644 --- a/writer/debugfs_writer.c +++ b/writer/debugfs_writer.c @@ -183,8 +183,10 @@ static ssize_t read_filter(struct file *file, char __user *user_buf, ssize_t ret; buf = kmalloc(len + 2, GFP_KERNEL); - memcpy(buf, name, len); + if (buf == NULL) + return -ENOMEM; + memcpy(buf, name, len); buf[len] = '\0'; buf[len + 1] = '\n'; diff --git a/writer/swap_msg.c b/writer/swap_msg.c index 838a30a..f915f6e 100644 --- a/writer/swap_msg.c +++ b/writer/swap_msg.c @@ -189,15 +189,11 @@ int swap_msg_pack_args(char *buf, int len, switch (fmt[fmt_i]) { case 'b': /* 1 byte(bool) */ - if (len < 1) - return -ENOMEM; *buf = (char)!!get_arg(regs, i); buf += 1; len -= 1; break; case 'c': /* 1 byte(char) */ - if (len < 1) - return -ENOMEM; *buf = (char)get_arg(regs, i); buf += 1; len -= 1; -- 2.7.4