From c757cffd26239450248bfd613855537499a719fd Mon Sep 17 00:00:00 2001 From: Kris Van Hees Date: Mon, 12 Aug 2013 05:27:40 -0400 Subject: [PATCH] dtrace: ensure memory allocation results are checked throughout the code Signed-off-by: Kris Van Hees --- include/linux/dtrace_os.h | 2 +- kernel/dtrace/dtrace_os.c | 35 ++++++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/include/linux/dtrace_os.h b/include/linux/dtrace_os.h index 3d2a71c6ae747..d8e564275cac4 100644 --- a/include/linux/dtrace_os.h +++ b/include/linux/dtrace_os.h @@ -29,7 +29,7 @@ extern void dtrace_os_exit(void); extern void dtrace_enable(void); extern void dtrace_disable(void); -extern void dtrace_invop_add(uint8_t (*func)(struct pt_regs *)); +extern int dtrace_invop_add(uint8_t (*func)(struct pt_regs *)); extern void dtrace_invop_remove(uint8_t (*func)(struct pt_regs *)); extern void dtrace_invop_enable(uint8_t *); diff --git a/kernel/dtrace/dtrace_os.c b/kernel/dtrace/dtrace_os.c index 0ceadf6f15e4e..1f5d923db9887 100644 --- a/kernel/dtrace/dtrace_os.c +++ b/kernel/dtrace/dtrace_os.c @@ -81,11 +81,8 @@ dtrace_psinfo_t *dtrace_psinfo_alloc(struct task_struct *task) struct mm_struct *mm; psinfo = kzalloc(sizeof(dtrace_psinfo_t), GFP_KERNEL); - if (psinfo == NULL) { - pr_warning("%s: cannot allocate DTrace psinfo structure\n", - __func__); - return NULL; - } + if (psinfo == NULL) + goto fail; mm = get_task_mm(task); if (mm) { @@ -125,6 +122,8 @@ dtrace_psinfo_t *dtrace_psinfo_alloc(struct task_struct *task) } psinfo->argv = vmalloc((psinfo->argc + 1) * sizeof(char *)); + if (psinfo->argv == NULL) + goto fail; /* * Now populate the array of argument strings. @@ -149,6 +148,8 @@ dtrace_psinfo_t *dtrace_psinfo_alloc(struct task_struct *task) } psinfo->envp = vmalloc((envc + 1) * sizeof(char *)); + if (psinfo->envp == NULL) + goto fail; /* * Now populate the array of environment variable strings. @@ -161,6 +162,19 @@ dtrace_psinfo_t *dtrace_psinfo_alloc(struct task_struct *task) } return psinfo; + +fail: + pr_warning("%s: cannot allocate DTrace psinfo structure\n", __func__); + if (psinfo) { + if (psinfo->argv == NULL) + vfree(psinfo->argv); + if (psinfo->envp == NULL) + vfree(psinfo->envp); + + kfree(psinfo); + } + + return NULL; } static DEFINE_SPINLOCK(psinfo_lock); @@ -554,14 +568,21 @@ void dtrace_disable(void) } EXPORT_SYMBOL(dtrace_disable); -void dtrace_invop_add(uint8_t (*func)(struct pt_regs *)) +int dtrace_invop_add(uint8_t (*func)(struct pt_regs *)) { dtrace_invop_hdlr_t *hdlr; hdlr = kmalloc(sizeof(dtrace_invop_hdlr_t), GFP_KERNEL); + if (hdlr == NULL) { + pr_warn("Failed to add invop handler: out of memory\n"); + return -ENOMEM; + } + hdlr->dtih_func = func; hdlr->dtih_next = dtrace_invop_hdlrs; dtrace_invop_hdlrs = hdlr; + + return 0; } EXPORT_SYMBOL(dtrace_invop_add); @@ -571,7 +592,7 @@ void dtrace_invop_remove(uint8_t (*func)(struct pt_regs *)) for (;;) { if (hdlr == NULL) - pr_err("attempt to remove non-existant invop handler"); + return; if (hdlr->dtih_func == func) break; -- 2.50.1