From: Mathieu Desnoyers Date: Wed, 25 May 2011 02:19:43 +0000 (-0400) Subject: Fix module get/put handling wrt data free (use after free) X-Git-Tag: v2.0-pre1~91 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=edeb3137b6064818f310567ded5c60e442a933e6;p=lttng-modules.git Fix module get/put handling wrt data free (use after free) Signed-off-by: Mathieu Desnoyers --- diff --git a/ltt-events.c b/ltt-events.c index c08079b5..84ad1de5 100644 --- a/ltt-events.c +++ b/ltt-events.c @@ -253,6 +253,8 @@ struct ltt_event *ltt_event_create(struct ltt_channel *chan, event); if (ret) goto register_error; + ret = try_module_get(event->desc->owner); + WARN_ON_ONCE(!ret); break; case LTTNG_KERNEL_FUNCTION: ret = lttng_ftrace_register(event_param->name, @@ -260,6 +262,8 @@ struct ltt_event *ltt_event_create(struct ltt_channel *chan, event); if (ret) goto register_error; + ret = try_module_get(event->desc->owner); + WARN_ON_ONCE(!ret); break; default: WARN_ON_ONCE(1); @@ -299,7 +303,6 @@ int _ltt_event_unregister(struct ltt_event *event) event); if (ret) return ret; - ltt_event_put(event->desc); break; case LTTNG_KERNEL_KPROBE: lttng_kprobes_unregister(event); @@ -321,7 +324,21 @@ int _ltt_event_unregister(struct ltt_event *event) static void _ltt_event_destroy(struct ltt_event *event) { - ltt_event_put(event->desc); + switch (event->instrumentation) { + case LTTNG_KERNEL_TRACEPOINT: + ltt_event_put(event->desc); + break; + case LTTNG_KERNEL_KPROBE: + module_put(event->desc->owner); + lttng_kprobes_destroy_private(event); + break; + case LTTNG_KERNEL_FUNCTION: + module_put(event->desc->owner); + lttng_ftrace_destroy_private(event); + break; + default: + WARN_ON_ONCE(1); + } list_del(&event->list); kmem_cache_free(event_cache, event); } diff --git a/ltt-events.h b/ltt-events.h index 4179fb7c..ce030ae3 100644 --- a/ltt-events.h +++ b/ltt-events.h @@ -269,6 +269,7 @@ int lttng_kprobes_register(const char *name, uint64_t addr, struct ltt_event *event); void lttng_kprobes_unregister(struct ltt_event *event); +void lttng_kprobes_destroy_private(struct ltt_event *event); #else static inline int lttng_kprobes_register(const char *name, @@ -284,6 +285,11 @@ static inline void lttng_kprobes_unregister(struct ltt_event *event) { } + +static inline +void lttng_kprobes_destroy_private(struct ltt_event *event) +{ +} #endif #ifdef CONFIG_DYNAMIC_FTRACE @@ -291,6 +297,7 @@ int lttng_ftrace_register(const char *name, const char *symbol_name, struct ltt_event *event); void lttng_ftrace_unregister(struct ltt_event *event); +void lttng_ftrace_destroy_private(struct ltt_event *event); #else static inline int lttng_ftrace_register(const char *name, @@ -304,6 +311,11 @@ static inline void lttng_ftrace_unregister(struct ltt_event *event) { } + +static inline +void lttng_ftrace_destroy_private(struct ltt_event *event) +{ +} #endif extern const struct file_operations lttng_tracepoint_list_fops; diff --git a/probes/lttng-ftrace.c b/probes/lttng-ftrace.c index c866876e..ec086902 100644 --- a/probes/lttng-ftrace.c +++ b/probes/lttng-ftrace.c @@ -146,12 +146,17 @@ void lttng_ftrace_unregister(struct ltt_event *event) { wrapper_unregister_ftrace_function_probe(event->u.ftrace.symbol_name, <tng_ftrace_ops, event); +} +EXPORT_SYMBOL_GPL(lttng_ftrace_unregister); + +void lttng_ftrace_destroy_private(struct ltt_event *event) +{ kfree(event->u.ftrace.symbol_name); kfree(event->desc->fields); kfree(event->desc->name); kfree(event->desc); } -EXPORT_SYMBOL_GPL(lttng_ftrace_unregister); +EXPORT_SYMBOL_GPL(lttng_ftrace_destroy_private); int lttng_ftrace_init(void) { diff --git a/probes/lttng-kprobes.c b/probes/lttng-kprobes.c index 650144cb..9dd3569b 100644 --- a/probes/lttng-kprobes.c +++ b/probes/lttng-kprobes.c @@ -136,12 +136,17 @@ EXPORT_SYMBOL_GPL(lttng_kprobes_register); void lttng_kprobes_unregister(struct ltt_event *event) { unregister_kprobe(&event->u.kprobe.kp); +} +EXPORT_SYMBOL_GPL(lttng_kprobes_unregister); + +void lttng_kprobes_destroy_private(struct ltt_event *event) +{ kfree(event->u.kprobe.symbol_name); kfree(event->desc->fields); kfree(event->desc->name); kfree(event->desc); } -EXPORT_SYMBOL_GPL(lttng_kprobes_unregister); +EXPORT_SYMBOL_GPL(lttng_kprobes_destroy_private); MODULE_LICENSE("GPL and additional rights"); MODULE_AUTHOR("Mathieu Desnoyers");