]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Cache rad_module_t in thread instance data to fix use after free issues
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 3 Apr 2018 10:18:10 +0000 (11:18 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 3 Apr 2018 10:18:10 +0000 (11:18 +0100)
src/include/modules.h
src/main/module.c

index e387709e3b8fa8495f451a47f4a332e3cf6da4d8..036da00f1e7742a5f33a61f25c99aaf6ff684175 100644 (file)
@@ -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;
index 7d619c9b02f0464b078b244f54a04ccc6ecf65af..30136d32f5625050356ccc2690062e485ce5b26b 100644 (file)
@@ -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) {