]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Allow atexit handlers to return error codes so we can track when they fail
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 9 Apr 2022 19:56:10 +0000 (14:56 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 9 Apr 2022 19:56:10 +0000 (14:56 -0500)
34 files changed:
src/bin/dhcpclient.c
src/bin/radclient.c
src/lib/eap_aka_sim/crypto.c
src/lib/io/network.c
src/lib/ldap/base.c
src/lib/redis/pipeline.c
src/lib/server/exec.c
src/lib/server/exec_legacy.c
src/lib/server/log.c
src/lib/server/module.c
src/lib/server/module_rlm.c
src/lib/server/module_rlm.h
src/lib/server/request.c
src/lib/server/virtual_servers.c
src/lib/server/virtual_servers.h
src/lib/tls/base.c
src/lib/tls/bio.c
src/lib/tls/log.c
src/lib/util/atexit.c
src/lib/util/atexit.h
src/lib/util/dict_util.c
src/lib/util/event.c
src/lib/util/hmac_md5.c
src/lib/util/hmac_sha1.c
src/lib/util/log.c
src/lib/util/md4.c
src/lib/util/md5.c
src/lib/util/regex.c
src/lib/util/sbuff.c
src/lib/util/sbuff.h
src/lib/util/strerror.c
src/lib/util/syserror.c
src/lib/util/talloc.c
src/modules/rlm_krb5/krb5.c

index cea0126e28af424b729137ad50e58c7c470255ce..d06da8ba5947e9e39f39d66648fb46439c64eaf4 100644 (file)
@@ -748,7 +748,11 @@ int main(int argc, char **argv)
        }
 
        fr_dhcpv4_global_free();
-       fr_dict_autofree(dhcpclient_dict);
+
+       if (fr_dict_autofree(dhcpclient_dict) < 0) {
+               fr_perror("dhcpclient");
+               ret = -1;
+       }
 
        /*
         *      Ensure our atexit handlers run before any other
index 9919a0daa9edca2e76584a8ecde02fa98609e0cd..72e795365afd5e407cbf5b43d53091212d2de8c3 100644 (file)
@@ -1098,6 +1098,7 @@ packet_done:
  */
 int main(int argc, char **argv)
 {
+       int             ret = EXIT_SUCCESS;
        int             c;
        char            const *raddb_dir = RADDBDIR;
        char            const *dict_dir = DICTDIR;
@@ -1621,7 +1622,10 @@ int main(int argc, char **argv)
 
        fr_radius_free();
 
-       fr_dict_autofree(radclient_dict);
+       if (fr_dict_autofree(radclient_dict) < 0) {
+               fr_perror("radclient");
+               ret = EXIT_FAILURE;
+       }
 
 #ifndef NDEBUG
        talloc_free(autofree);
@@ -1650,5 +1654,5 @@ int main(int argc, char **argv)
 
        if ((stats.lost > 0) || (stats.failed > 0)) return EXIT_FAILURE;
 
-       return EXIT_SUCCESS;
+       return ret;
 }
index a37f1b364040a89748ea958b042849b5ddb0c24f..cf3d5659507d0b97363a6f79f2d6c9f5ed1df7c7 100644 (file)
@@ -56,9 +56,10 @@ RCSID("$Id$")
  */
 static _Thread_local EVP_CIPHER_CTX *evp_chipher_ctx;
 
-static void _evp_cipher_ctx_free_on_exit(void *arg)
+static int _evp_cipher_ctx_free_on_exit(void *arg)
 {
        EVP_CIPHER_CTX_free(arg);
+       return 0;
 }
 
 /** Allocate and reset a resumable EVP_CIPHER_CTX for each thread
index 271d9686b3db5687d12b3d51947c7365cec5f232..25d026e379e7ef20da3254b80891949b50fa5b46 100644 (file)
@@ -193,9 +193,9 @@ static int8_t socket_num_cmp(void const *one, void const *two)
  *     Explicitly cleanup the memory allocated to the ring buffer,
  *     just in case valgrind complains about it.
  */
-static void _fr_network_rb_free(void *arg)
+static int _fr_network_rb_free(void *arg)
 {
-       talloc_free(arg);
+       return talloc_free(arg);
 }
 
 /** Initialise thread local storage
index bfca162b1ab0ebfeb7c59e8f603bee353124bd79..358dfd8efd008022111e2da18c6cb17416bc5235 100644 (file)
@@ -897,9 +897,10 @@ fr_ldap_query_t *fr_ldap_modify_alloc(TALLOC_CTX *ctx, char const *dn,
        return query;
 }
 
-static void _ldap_handle_thread_local_free(void *handle)
+static int _ldap_handle_thread_local_free(void *handle)
 {
-       ldap_unbind_ext_s(handle, NULL, NULL);
+       if (ldap_unbind_ext_s(handle, NULL, NULL) < 0) return -1;
+       return 0;
 }
 
 /** Get a thread local dummy LDAP handle
index e2daf5ebcad566d8baeca7576d3bb49055e28935..1633dda4fb34fc7ae83194dc69a40086d195da11 100644 (file)
@@ -152,7 +152,7 @@ struct fr_redis_trunk_s {
 /** Free any free requests when the thread is joined
  *
  */
-static void _command_set_free_list_free_on_exit(void *arg)
+static int _command_set_free_list_free_on_exit(void *arg)
 {
        fr_dlist_head_t         *list = talloc_get_type_abort(arg, fr_dlist_head_t);
        fr_redis_command_set_t  *cmds;
@@ -160,8 +160,8 @@ static void _command_set_free_list_free_on_exit(void *arg)
        /*
         *      See the destructor for why this works
         */
-       while ((cmds = fr_dlist_head(list))) talloc_free(cmds);
-       talloc_free(list);
+       while ((cmds = fr_dlist_head(list))) if (talloc_free(cmds) < 0) return -1;
+       return talloc_free(list);
 }
 
 /** Free a command set
index a7f7da3045b216a0d582818edea1856c90420e35..7e35562d10eadf5816f52265cc8f4802d9298624 100644 (file)
@@ -314,8 +314,7 @@ static NEVER_RETURNS void exec_child(request_t *request, char **argv, char **env
        /*
         *      Disarm the thread local destructors
         *
-        *      FIXME - Leaving them enabled causes issues in child
-        *      execd processes, but we should really track down why.
+        *      It's not safe to free memory between fork and exec.
         */
        fr_atexit_thread_local_disarm_all();
 
index e22aefa38bb250d5df3340b2f78ede5f8a924a30..5df3ac2d3dda38fe76d69fa811e886c6b6a23208 100644 (file)
@@ -201,8 +201,7 @@ static NEVER_RETURNS void exec_child_legacy(request_t *request, char **argv, cha
        /*
         *      Disarm the thread local destructors
         *
-        *      FIXME - Leaving them enabled causes issues in child
-        *      execd processes, but we should really track down why.
+        *      It's not safe to free memory between fork and exec.
         */
        fr_atexit_thread_local_disarm_all();
 
index 49b73b847f168dc53791c5f6ca6201717620b824..305f2a40f641947edb5706736b421d1aa8faa610 100644 (file)
@@ -243,9 +243,9 @@ inline bool log_rdebug_enabled(fr_log_lvl_t lvl, request_t const *request)
 /** Cleanup the memory pool used by vlog_request
  *
  */
-static void _fr_vlog_request_pool_free(void *arg)
+static int _fr_vlog_request_pool_free(void *arg)
 {
-       talloc_free(arg);
+       return talloc_free(arg);
 }
 
 /** Send a log message to its destination, possibly including fields from the request
@@ -709,9 +709,9 @@ void log_request_perror(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request
 /** Cleanup the memory pool used by the OID sbuff
  *
  */
-static void _fr_log_request_oid_buff_free(void *arg)
+static int _fr_log_request_oid_buff_free(void *arg)
 {
-       talloc_free(arg);
+       return talloc_free(arg);
 }
 
 /** Allocate an extensible sbuff for printing OID strings
index 969e6155c7e3c84058d17645cea5e5afa462a442..7d579a409bc615115f3b2d4dc8bfc3570fb16656 100644 (file)
@@ -564,7 +564,7 @@ static int _module_thread_inst_free(module_thread_instance_t *ti)
  *
  * All thread local module lists should have been destroyed by this point
  */
-static void _module_thread_inst_list_free(void *tilp)
+static int _module_thread_inst_list_free(void *tilp)
 {
        module_thread_instance_t **til = talloc_get_type_abort(tilp, module_thread_instance_t *);
        size_t i, len = talloc_array_length(til);
@@ -576,10 +576,10 @@ static void _module_thread_inst_list_free(void *tilp)
        if (!fr_cond_assert_msg(found == 0,
                                "Thread local array has %u non-null elements remaining on exit.  This is a leak",
                                found)) {
-               return;
+               return -1;
        }
 
-       talloc_free(til);
+       return talloc_free(til);
 }
 
 /** Creates per-thread instance data for modules which need it
@@ -1102,13 +1102,17 @@ static void _module_global_list_init(void *uctx)
        MEM(module_global_inst_list = fr_heap_alloc(NULL, _module_instance_global_cmp, module_instance_t, inst_idx, 256));
 }
 
-static void _module_global_list_free(UNUSED void *uctx)
+static int _module_global_list_free(UNUSED void *uctx)
 {
        if (!fr_cond_assert_msg(fr_heap_num_elements(module_global_inst_list) == 0,
                                "Global module heap has %u elements remaining on exit.  This is a leak",
-                               fr_heap_num_elements(module_global_inst_list))) return;
-       TALLOC_FREE(module_global_inst_list);
-       TALLOC_FREE(dl_modules);
+                               fr_heap_num_elements(module_global_inst_list))) return -1;
+       if (talloc_free(module_global_inst_list) < 0) return -1;
+       module_global_inst_list = NULL;
+
+       if (talloc_free(dl_modules) < 0) return -1;
+       dl_modules = NULL;
+       return 0;
 }
 
 /** Perform global initialisation for modules
index b25829c5802339978b51550b8976c275e7da1e95..a9e01f6a35f03b101f0eff55e79a3e5ca972f6bb 100644 (file)
@@ -1163,15 +1163,19 @@ int modules_rlm_bootstrap(CONF_SECTION *root)
  *
  * Automatically called on exit.
  */
-void modules_rlm_free(void)
+int modules_rlm_free(void)
 {
-       TALLOC_FREE(rlm_modules);
-       TALLOC_FREE(module_rlm_virtual_name_tree);
+       if (talloc_free(rlm_modules) < 0) return -1;
+       rlm_modules = NULL;
+       if (talloc_free(module_rlm_virtual_name_tree) < 0) return -1;
+       module_rlm_virtual_name_tree = NULL;
+
+       return 0;
 }
 
-static void _modules_rlm_free_atexit(UNUSED void *uctx)
+static int _modules_rlm_free_atexit(UNUSED void *uctx)
 {
-       modules_rlm_free();
+       return modules_rlm_free();
 }
 
 /** Initialise the module list structure
index 904b9e06cb35b39d78a1ebb0c667b707eddcadfe..0f86cc4397e2f7fecaf42a830dc68e84874f2db6 100644 (file)
@@ -123,7 +123,7 @@ int         modules_rlm_bootstrap(CONF_SECTION *root) CC_HINT(nonnull);
  *
  * @{
  */
-void           modules_rlm_free(void);
+int            modules_rlm_free(void);
 
 int            modules_rlm_init(void);
 /** @} */
index 19cf78a7aef0ca6c4401132f9b52b5e41630cd46..635093fc1046331daa667d9b00f7dcf8616813c5 100644 (file)
@@ -370,7 +370,7 @@ really_free:
 /** Free any free requests when the thread is joined
  *
  */
-static void _request_free_list_free_on_exit(void *arg)
+static int _request_free_list_free_on_exit(void *arg)
 {
        fr_dlist_head_t *list = talloc_get_type_abort(arg, fr_dlist_head_t);
        request_t               *request;
@@ -378,8 +378,8 @@ static void _request_free_list_free_on_exit(void *arg)
        /*
         *      See the destructor for why this works
         */
-       while ((request = fr_dlist_head(list))) talloc_free(request);
-       talloc_free(list);
+       while ((request = fr_dlist_head(list))) if (talloc_free(request) < 0) return -1;
+       return talloc_free(list);
 }
 
 static inline CC_HINT(always_inline) request_t *request_alloc_pool(TALLOC_CTX *ctx)
index ff68831f26b04847385c2ced93357443a8c97521..c63c92b75a84d41ba1a0b32a836049af5cd57195 100644 (file)
@@ -1396,18 +1396,24 @@ int virtual_servers_bootstrap(CONF_SECTION *config)
        return 0;
 }
 
-void virtual_servers_free(void)
+int virtual_servers_free(void)
 {
-       TALLOC_FREE(listen_addr_root);
-       TALLOC_FREE(server_section_name_tree);
-       TALLOC_FREE(process_modules);
-       TALLOC_FREE(proto_modules);
-       fr_dict_autofree(virtual_server_dict_autoload);
+       if (talloc_free(listen_addr_root) < 0) return -1;
+       listen_addr_root = NULL;
+       if (talloc_free(server_section_name_tree) < 0) return -1;
+       server_section_name_tree = NULL;
+       if (talloc_free(process_modules) < 0) return -1;
+       process_modules = NULL;
+       if (talloc_free(proto_modules) < 0) return -1;
+       proto_modules = NULL;
+       if (fr_dict_autofree(virtual_server_dict_autoload) < 0) return -1;
+
+       return 0;
 }
 
-static void _virtual_servers_atexit(UNUSED void *uctx)
+static int _virtual_servers_atexit(UNUSED void *uctx)
 {
-       virtual_servers_free();
+       return virtual_servers_free();
 }
 
 /** Performs global initialisation for the virtual server code
index 27c12ad377afb5e7417300e4e8e34fcfb087372a..72482f89ecbbaa29c39dcb7ad7c96469ddb96945 100644 (file)
@@ -124,7 +124,7 @@ int         virtual_servers_instantiate(void) CC_HINT(nonnull);
 
 int            virtual_servers_bootstrap(CONF_SECTION *config) CC_HINT(nonnull);
 
-void           virtual_servers_free(void);
+int            virtual_servers_free(void);
 
 int            virtual_servers_init(void) CC_HINT(nonnull);
 /** @} */
index c577c2f15b1e3bf9ffd1110105bdb6cc25e53695..30e6bc02b464b9c6ffd2144bcbd9d5e21b0dec3a 100644 (file)
@@ -285,10 +285,10 @@ static void fr_openssl_talloc_free(void *to_free, char const *file, int line)
 /** Cleanup async pools if the thread exits
  *
  */
-static void _openssl_thread_free(void *init)
+static int _openssl_thread_free(void *init)
 {
        ASYNC_cleanup_thread();
-       talloc_free(init);
+       return talloc_free(init);
 }
 
 /** Perform thread-specific initialisation for OpenSSL
@@ -362,9 +362,10 @@ static void _openssl_engine_free(void)
 }
 #endif
 
-static void fr_openssl_cleanup(UNUSED void *uctx)
+static int fr_openssl_cleanup(UNUSED void *uctx)
 {
        OPENSSL_cleanup();
+       return 0;
 }
 
 /** Add all the default ciphers and message digests to our context.
index a9ac84523c992e12c05d243505cd9a985154f6d1..705f1d46823717ad732eea940f3e5e977e842bff 100644 (file)
@@ -324,11 +324,11 @@ void fr_tls_bio_dbuff_thread_local_clear(void)
 /** Frees the thread local TALLOC bio and its underlying OpenSSL BIO *
  *
  */
-static void _fr_tls_bio_dbuff_thread_local_free(void *bio_talloc_agg)
+static int _fr_tls_bio_dbuff_thread_local_free(void *bio_talloc_agg)
 {
        fr_tls_bio_dbuff_t      *our_bio_talloc_agg = talloc_get_type_abort(bio_talloc_agg, fr_tls_bio_dbuff_t);
 
-       talloc_free(our_bio_talloc_agg);                        /* Frees the #fr_tls_bio_dbuff_t and BIO */
+       return talloc_free(our_bio_talloc_agg);                 /* Frees the #fr_tls_bio_dbuff_t and BIO */
 }
 
 /** Return a BIO which will aggregate data in an expandable talloc buffer
index d1b9ad4123c5f1cd85455b3abd673325a8eff205..5d8f58b8599c80694cb78405bf208b26bac20a31 100644 (file)
@@ -733,13 +733,13 @@ static int tls_log_global_bio_free_cb(BIO *bio)
 /** Frees a logging bio and its underlying OpenSSL BIO *
  *
  */
-static void _fr_tls_log_bio_free(void *log_bio)
+static int _fr_tls_log_bio_free(void *log_bio)
 {
        fr_tls_log_bio_t        *our_log_bio = talloc_get_type_abort(log_bio, fr_tls_log_bio_t);
 
        BIO_free(our_log_bio->bio);
        our_log_bio->bio = NULL;
-       talloc_free(our_log_bio);
+       return talloc_free(our_log_bio);
 }
 
 /** Return a request log BIO to use with OpenSSL logging functions
index 8e419e82f2b645f82820a42e3d35a3ee21b6e6c5..b4c8fb0128d6759530274023a8ac433ae3bc2501 100644 (file)
@@ -141,11 +141,20 @@ static int _thread_local_list_free(fr_atexit_list_t *list)
  *
  * @param[in] list     The thread-specific exit handler list.
  */
-static void _thread_local_free(void *list)
+static void _thread_local_pthread_free(void *list)
 {
        talloc_free(list);
 }
 
+/** Run all the thread local destructors
+ *
+ * @param[in] list     The thread-specific exit handler list.
+ */
+static int _thread_local_free(void *list)
+{
+       return talloc_free(list);
+}
+
 /** Talloc destructor for freeing list elements in order
  *
  */
@@ -252,7 +261,7 @@ int _fr_atexit_thread_local(NDEBUG_LOCATION_ARGS
                             (unsigned int)pthread_self(), list);
 
                fr_dlist_talloc_init(&list->head, fr_atexit_entry_t, entry);
-               (void) pthread_key_create(&list->key, _thread_local_free);
+               (void) pthread_key_create(&list->key, _thread_local_pthread_free);
 
                /*
                 *      We need to pass in a pointer to the heap
@@ -356,10 +365,14 @@ void fr_atexit_thread_local_disarm_all(void)
  *
  * One example is the OpenSSL log BIOs which must be cleaned up
  * before fr_openssl_free is called.
+ *
+ * @return
+ *      - >= 0 The number of atexit handlers triggered on success.
+ *      - <0 the return code from any atexit handlers that returned an error.
  */
-unsigned int fr_atexit_thread_trigger_all(void)
+int fr_atexit_thread_trigger_all(void)
 {
-       fr_atexit_entry_t               *e = NULL, *ee;
+       fr_atexit_entry_t               *e = NULL, *ee, *to_free;
        fr_atexit_list_t                *list;
        unsigned int                    count = 0;
 
@@ -380,7 +393,14 @@ unsigned int fr_atexit_thread_trigger_all(void)
                                     list, ee, ee->func, ee->uctx, ee->file, ee->line);
 
                        count++;
-                       ee = fr_dlist_talloc_free_item(&list->head, ee);
+                       to_free = ee;
+                       ee = fr_dlist_remove(&list->head, ee);
+                       if (talloc_free(to_free) < 0) {
+                               fr_strerror_printf_push("atexit handler failed %p/%p func=%p, uctx=%p (alloced %s:%u)",
+                                                       list, to_free,
+                                                       to_free->func, to_free->uctx, to_free->file, to_free->line);
+                               return -1;
+                       }
                }
        }
 
@@ -451,10 +471,14 @@ void fr_atexit_global_disarm_all(void)
  * atexit handlers using the normal POSIX mechanism, and we need
  * to ensure all our atexit handlers fire before so any global
  * deinit is done explicitly by us.
+ *
+ * @return
+ *      - >= 0 The number of atexit handlers triggered on success.
+ *      - <0 the return code from any atexit handlers that returned an error.
  */
-unsigned int fr_atexit_global_trigger_all(void)
+int fr_atexit_global_trigger_all(void)
 {
-       fr_atexit_entry_t               *e = NULL;
+       fr_atexit_entry_t               *e = NULL, *to_free;
        unsigned int                    count = 0;
 
        /*
@@ -468,7 +492,14 @@ unsigned int fr_atexit_global_trigger_all(void)
                             fr_atexit_global, e, e->func, e->uctx, e->file, e->line);
 
                count++;
-               e = fr_dlist_talloc_free_item(&fr_atexit_global->head, e);
+               to_free = e;
+               e = fr_dlist_remove(&fr_atexit_global->head, e);
+               if (talloc_free(to_free) < 0) {
+                       fr_strerror_printf_push("atexit handler failed %p/%p func=%p, uctx=%p (alloced %s:%u)",
+                                               fr_atexit_global, to_free,
+                                               to_free->func, to_free->uctx, to_free->file, to_free->line);
+                       return -1;
+               }
        }
 
        return count;
@@ -484,11 +515,13 @@ unsigned int fr_atexit_global_trigger_all(void)
  * @param[in] uctx_scope       Only process entries where the func and scope both match.
  * @param[in] func             Entries matching this function will be triggered.
  * @param[in] uctx             associated with the entry.
- * @return How many triggers fired.
+ * @return
+ *      - >= 0 The number of atexit handlers triggered on success.
+ *      - <0 the return code from any atexit handlers that returned an error.
  */
-unsigned int fr_atexit_trigger(bool uctx_scope, fr_atexit_t func, void const *uctx)
+int fr_atexit_trigger(bool uctx_scope, fr_atexit_t func, void const *uctx)
 {
-       fr_atexit_entry_t               *e = NULL, *ee;
+       fr_atexit_entry_t               *e = NULL, *ee, *to_free;
        fr_atexit_list_t                *list;
        unsigned int                    count = 0;
 
@@ -505,7 +538,14 @@ unsigned int fr_atexit_trigger(bool uctx_scope, fr_atexit_t func, void const *uc
                             fr_atexit_global, e, e->func, e->uctx, e->file, e->line);
 
                count++;
-               e = fr_dlist_talloc_free_item(&fr_atexit_global->head, e);
+               to_free = e;
+               e = fr_dlist_remove(&fr_atexit_global->head, e);
+               if (talloc_free(to_free) < 0) {
+                       fr_strerror_printf_push("atexit handler failed %p/%p func=%p, uctx=%p (alloced %s:%u)",
+                                               fr_atexit_global, to_free,
+                                               to_free->func, to_free->uctx, to_free->file, to_free->line);
+                       return -1;
+               }
        }
        e = NULL;
 
@@ -531,7 +571,14 @@ do_threads:
                                     list, ee, ee->func, ee->uctx, ee->file, ee->line);
 
                        count++;
-                       ee = fr_dlist_talloc_free_item(&list->head, ee);
+                       to_free = ee;
+                       ee = fr_dlist_remove(&list->head, ee);
+                       if (talloc_free(to_free) < 0) {
+                               fr_strerror_printf_push("atexit handler failed %p/%p func=%p, uctx=%p (alloced %s:%u)",
+                                                       list, to_free,
+                                                       to_free->func, to_free->uctx, to_free->file, to_free->line);
+                               return -1;
+                       }
                }
        }
 
index e8b42a11b7eb040e5efdcf5732c09fb5b4761b42..9d80f1ca25da9bcbdb330b72033db09e49e8e72e 100644 (file)
@@ -45,7 +45,7 @@ extern "C" {
  *
  * @param[in] uctx     to free.
  */
-typedef void(*fr_atexit_t)(void *uctx);
+typedef int(*fr_atexit_t)(void *uctx);
 
 int fr_atexit_global_setup(void);
 
@@ -117,15 +117,15 @@ unsigned int      fr_atexit_thread_local_disarm(bool uctx_scope, fr_atexit_t func, vo
 
 void           fr_atexit_thread_local_disarm_all(void);
 
-unsigned int   fr_atexit_thread_trigger_all(void);
+int            fr_atexit_thread_trigger_all(void);
 
 unsigned int   fr_atexit_global_disarm(bool uctx_scope, fr_atexit_t func, void const *uctx);
 
 void           fr_atexit_global_disarm_all(void);
 
-unsigned int   fr_atexit_global_trigger_all(void);
+int            fr_atexit_global_trigger_all(void);
 
-unsigned int   fr_atexit_trigger(bool uctx_scope, fr_atexit_t func, void const *uctx);
+int            fr_atexit_trigger(bool uctx_scope, fr_atexit_t func, void const *uctx);
 
 bool           fr_atexit_is_exiting(void);
 
index 4e3b1501bd7dc703734ff60baf2cb4969f7c7d53..7f98222e368ea3200992789504fb7a98013aae3b 100644 (file)
@@ -3618,9 +3618,9 @@ static int _dict_validation_onload(dl_t const *dl, void *symbol, UNUSED void *us
        return 0;
 }
 
-static void _dict_global_free_at_exit(void *uctx)
+static int _dict_global_free_at_exit(void *uctx)
 {
-       talloc_free(uctx);
+       return talloc_free(uctx);
 }
 
 static int _dict_global_free(fr_dict_gctx_t *gctx)
index fa1e63e687211e0f04cdf712ad6c39cd5503b2e0..27274ef43c4d09343f2ec1ae0ee828a2f633ff1b 100644 (file)
@@ -2583,11 +2583,12 @@ static int _event_list_free(fr_event_list_t *el)
 /** Free any memory we allocated for indexes
  *
  */
-static void _event_free_indexes(UNUSED void *uctx)
+static int _event_free_indexes(UNUSED void *uctx)
 {
        unsigned int i;
 
-       for (i = 0; i < NUM_ELEMENTS(filter_maps); i++) talloc_free(filter_maps[i].ev_to_func);
+       for (i = 0; i < NUM_ELEMENTS(filter_maps); i++) if (talloc_free(filter_maps[i].ev_to_func) < 0) return -1;
+       return 0;
 }
 
 static void _event_build_indexes(UNUSED void *uctx)
index 630138e69bf3d07bdedaa0fa21c2ad2e5307923a..3432d82e70ccc491bbd10bf6cd63363adb638d4b 100644 (file)
@@ -40,9 +40,10 @@ RCSID("$Id$")
 
 static _Thread_local EVP_MD_CTX *md5_hmac_ctx;
 
-static void _hmac_md5_ctx_free_on_exit(void *arg)
+static int _hmac_md5_ctx_free_on_exit(void *arg)
 {
        EVP_MD_CTX_free(arg);
+       return 0;
 }
 
 /** Calculate HMAC using OpenSSL's MD5 implementation
index 36eb44e1dbd14fed1b65d38b617c067a672f2784..4a3248a5337b73485d00af6dd21370e3dd0fe5f7 100644 (file)
@@ -45,9 +45,10 @@ unsigned int sha1_data_problems = 0;
 
 static _Thread_local EVP_MD_CTX *sha1_hmac_ctx;
 
-static void _hmac_sha1_ctx_free_on_exit(void *arg)
+static int _hmac_sha1_ctx_free_on_exit(void *arg)
 {
        EVP_MD_CTX_free(arg);
+       return 0;
 }
 
 /** Calculate HMAC using OpenSSL's SHA1 implementation
index fba985a2129debfd7d396089778ee215da6da482..876850d338a2adf9a9942ed854fd697911b6bdb6 100644 (file)
@@ -298,10 +298,11 @@ fr_log_t default_log = {
 /** Cleanup the memory pool used by vlog_request
  *
  */
-static void _fr_log_pool_free(void *arg)
+static int _fr_log_pool_free(void *arg)
 {
-       talloc_free(arg);
+       if (talloc_free(arg) < 0) return -1;
        fr_log_pool = NULL;
+       return 0;
 }
 
 /** talloc ctx to use when composing log messages
index d47bab9647a5c590b66b87d5dd656dc3df5e0295..65ef8b2c44b1b0bfd41dadeaef4573058b6b639e 100644 (file)
@@ -491,7 +491,7 @@ void fr_md4_calc(uint8_t out[static MD4_DIGEST_LENGTH], uint8_t const *in, size_
        fr_md4_ctx_free_from_list(&ctx);
 }
 
-static void _md4_ctx_free_on_exit(void *arg)
+static int _md4_ctx_free_on_exit(void *arg)
 {
        int i;
        fr_md4_free_list_t *free_list = arg;
@@ -501,7 +501,7 @@ static void _md4_ctx_free_on_exit(void *arg)
 
                fr_md4_ctx_free(&free_list[i].md_ctx);
        }
-       talloc_free(free_list);
+       return talloc_free(free_list);
 }
 
 /** @copydoc fr_md4_ctx_alloc
index 67d704775572fc2d1246cdd75c4462c1ce8d495e..e7434a20e53d9d0eb85e90012f5f71902858fce1 100644 (file)
@@ -464,7 +464,7 @@ void fr_md5_calc(uint8_t out[static MD5_DIGEST_LENGTH], uint8_t const *in, size_
        fr_md5_ctx_free_from_list(&ctx);
 }
 
-static void _md5_ctx_free_on_exit(void *arg)
+static int _md5_ctx_free_on_exit(void *arg)
 {
        int i;
        fr_md5_free_list_t *free_list = arg;
@@ -474,7 +474,7 @@ static void _md5_ctx_free_on_exit(void *arg)
 
                fr_md5_ctx_free(&free_list[i].md_ctx);
        }
-       talloc_free(free_list);
+       return talloc_free(free_list);
 }
 
 /** @copydoc fr_md5_ctx_alloc
index 73ca64ca4c0e5b77edb2c84f8a9f35e3b957a508..ec78e136e0981f56fb5d6949d6cecf0359fa61b3 100644 (file)
@@ -107,9 +107,9 @@ static int _pcre2_tls_free(fr_pcre2_tls_t *tls)
        return 0;
 }
 
-static void _pcre2_tls_free_on_exit(void *arg)
+static int _pcre2_tls_free_on_exit(void *arg)
 {
-       talloc_free(arg);
+       return talloc_free(arg);
 }
 
 /** Thread local init for pcre2
@@ -704,9 +704,9 @@ static int _pcre_tls_free(fr_pcre_tls_t *tls)
        return 0;
 }
 
-static void _pcre_tls_free_on_exit(void *arg)
+static int _pcre_tls_free_on_exit(void *arg)
 {
-       talloc_free(arg);
+       return talloc_free(arg);
 }
 
 /** Performs thread local storage initialisation for libpcre
index f221959f87c85fac2170806525c8e41ad6f353e9..4f00ba5ee67e3b76f6c5d899169eeee61cf85e86 100644 (file)
@@ -1424,9 +1424,9 @@ ssize_t fr_sbuff_in_bstrcpy_buffer(fr_sbuff_t *sbuff, char const *str)
 /** Free the scratch buffer used for printf
  *
  */
-static void _sbuff_scratch_free(void *arg)
+static int _sbuff_scratch_free(void *arg)
 {
-       talloc_free(arg);
+       return talloc_free(arg);
 }
 
 static inline CC_HINT(always_inline) int sbuff_scratch_init(TALLOC_CTX **out)
index d30fb3f1769013628e3396fd59169a371cef94b2..7fa3d91fad7e9130f638c790eb8d95113635ca9d 100644 (file)
@@ -541,9 +541,9 @@ typedef struct {
        fr_sbuff_uctx_talloc_t          tctx;           //!< Thread local tctx.
 } fr_sbuff_thread_local_t;
 
-static inline void _sbuff_thread_local_free(void *sbtl)
+static inline int _sbuff_thread_local_free(void *sbtl)
 {
-       talloc_free(sbtl);
+       return talloc_free(sbtl);
 }
 
 /** Create a function local and thread local extensible sbuff
index eb50b1853fd765e7b15b9715dac34690076f10ed..90224ef60d5e81abbbc6be3f3f06161ec936082d 100644 (file)
@@ -63,17 +63,19 @@ static _Thread_local bool logging_stop;     //!< Due to ordering issues we may get e
  *     Explicitly cleanup the memory allocated to the error buffer,
  *     just in case valgrind complains about it.
  */
-static void _fr_logging_free(void *arg)
+static int _fr_logging_free(void *arg)
 {
        /*
         *      Free arg instead of thread local storage
         *      as address sanitizer does a better job
         *      of tracking and doesn't report a leak.
         */
-       talloc_free(arg);
+       if (talloc_free(arg) < 0) return -1;
        fr_strerror_buffer = NULL;
 
        logging_stop = true;
+
+       return 0;
 }
 
 /** Initialise thread local storage
index 14e6c8a8839aa12551a06752964bf6992610ebfc..3250133195fb548dbd04d377f848b46b9933b16b 100644 (file)
@@ -43,10 +43,12 @@ static _Thread_local bool logging_stop;     //!< Due to ordering issues we may get e
  *     Explicitly cleanup the memory allocated to the error buffer,
  *     just in case valgrind complains about it.
  */
-static void _fr_logging_free(UNUSED void *arg)
+static int _fr_logging_free(UNUSED void *arg)
 {
-       TALLOC_FREE(fr_syserror_buffer);
+       if (talloc_free(fr_syserror_buffer) < 0) return -1;
+       fr_syserror_buffer = NULL;
        logging_stop = true;
+       return 0;
 }
 
 /** POSIX-2008 errno macros
index cc4d9335af62685f17d4368fecaf88ac96a71f08..c8a324237313a9b7abcfa43f993cfb332c38017b 100644 (file)
@@ -768,10 +768,10 @@ void **talloc_array_null_strip(void **array)
 /** Callback to free the autofree ctx on global exit
  *
  */
-static void _autofree_on_exit(void *af)
+static int _autofree_on_exit(void *af)
 {
        talloc_set_destructor(af, NULL);
-       talloc_free(af);
+       return talloc_free(af);
 }
 
 /** Ensures in the autofree ctx is manually freed, things don't explode atexit
index 9d1809d2c9ebbc8ea0d269f39b22480c45810bd2..55e99b4d892d1001dcd58d799411bdd26833e2ad 100644 (file)
@@ -38,9 +38,9 @@ static _Thread_local char *krb5_error_buffer;
 /*
  *     Explicitly cleanup the memory allocated to the error buffer.
  */
-static void _krb5_logging_free(void *arg)
+static int _krb5_logging_free(void *arg)
 {
-       talloc_free(arg);
+       return talloc_free(arg);
 }
 
 char const *rlm_krb5_error(rlm_krb5_t const *inst, krb5_context context, krb5_error_code code)