From: Arran Cudbard-Bell Date: Tue, 3 Apr 2018 10:18:10 +0000 (+0100) Subject: Cache rad_module_t in thread instance data to fix use after free issues X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dcbb3d4601a90d6564770b1178b8fbbeb7de392a;p=thirdparty%2Ffreeradius-server.git Cache rad_module_t in thread instance data to fix use after free issues --- diff --git a/src/include/modules.h b/src/include/modules.h index e387709e3b8..036da00f1e7 100644 --- a/src/include/modules.h +++ b/src/include/modules.h @@ -231,15 +231,17 @@ typedef struct { * Stores module and thread specific data. */ typedef struct { + void *data; //!< Thread specific instance data. + fr_event_list_t *el; //!< Event list associated with this thread. + rad_module_t const *module; //!< Public module structure. Cached for convenience, + ///< and to prevent use-after-free if the global data + ///< is freed before the thread instance data. + void *mod_inst; //!< Avoids thread_inst->inst->dl_inst->data. ///< This is in the hot path, so it makes sense. - module_instance_t *inst; //!< Non-thread local instance of this - - void *data; //!< Thread specific instance data. - uint64_t total_calls; //! total number of times we've been called uint64_t active_callers; //! number of active callers. i.e. number of current yields } module_thread_instance_t; diff --git a/src/main/module.c b/src/main/module.c index 7d619c9b02f..30136d32f56 100644 --- a/src/main/module.c +++ b/src/main/module.c @@ -492,8 +492,8 @@ static void _module_thread_instance_free(void *to_free) { module_thread_instance_t *ti = talloc_get_type_abort(to_free, module_thread_instance_t); - if (ti->inst->module->thread_detach) { - (void) ti->inst->module->thread_detach(ti->el, ti->data); + if (ti->module->thread_detach) { + (void) ti->module->thread_detach(ti->el, ti->data); } talloc_free(ti); @@ -548,7 +548,7 @@ static int _module_thread_instantiate(void *instance, void *ctx) MEM(ti = talloc_zero(NULL, module_thread_instance_t)); ti->el = thread_inst_ctx->el; - ti->inst = mi; + ti->module = mi->module; ti->mod_inst = mi->dl_inst->data; /* For efficient lookups */ if (mi->module->thread_inst_size) {