From: Arran Cudbard-Bell Date: Sat, 14 Dec 2019 11:38:21 +0000 (+0700) Subject: Don't crash on exit in threaded mode when using rlm_radius X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e1d4111dcdf4fb5fb2e2a18479f50671592b9549;p=thirdparty%2Ffreeradius-server.git Don't crash on exit in threaded mode when using rlm_radius --- diff --git a/src/lib/server/request.c b/src/lib/server/request.c index 8911b50ee70..cdc965e2ce9 100644 --- a/src/lib/server/request.c +++ b/src/lib/server/request.c @@ -266,6 +266,23 @@ REQUEST *request_alloc(TALLOC_CTX *ctx) return request; } +/** Allocate a request that's not in the free list + * + * This can be useful if modules need a persistent request for their own purposes + * which needs to be outside of the normal free list, so that it can be freed + * when the module requires, not when the thread destructor runs. + */ +REQUEST *request_alloc_local(TALLOC_CTX *ctx) +{ + REQUEST *request; + + MEM(request = talloc_zero(ctx, REQUEST)); + + request_init(request); + + return request; +} + static REQUEST *request_init_fake(REQUEST *request, REQUEST *fake) { fake->number = request->child_number++; diff --git a/src/lib/server/request.h b/src/lib/server/request.h index c23597c76d3..9cf6756e109 100644 --- a/src/lib/server/request.h +++ b/src/lib/server/request.h @@ -177,6 +177,8 @@ struct fr_request_s { REQUEST *request_alloc(TALLOC_CTX *ctx); +REQUEST *request_alloc_local(TALLOC_CTX *ctx); + REQUEST *request_alloc_fake(REQUEST *parent, fr_dict_t const *namespace); REQUEST *request_alloc_detachable(REQUEST *request, fr_dict_t const *namespace); diff --git a/src/modules/rlm_radius/rlm_radius_udp.c b/src/modules/rlm_radius/rlm_radius_udp.c index fc2a79de89a..0451cf824de 100644 --- a/src/modules/rlm_radius/rlm_radius_udp.c +++ b/src/modules/rlm_radius/rlm_radius_udp.c @@ -2597,7 +2597,15 @@ static fr_connection_state_t _conn_open(UNUSED fr_event_list_t *el, void *h, voi u = talloc_zero(c, fr_io_request_t); - request = request_alloc(u); + /* + * Allocate outside of the free list. + * There appears to be an issue where + * the thread destructor runs too + * early, and frees the freelist's + * head before the module destructor + * runs. + */ + request = request_alloc_local(u); request->async = talloc_zero(request, fr_async_t); talloc_const_free(request->name); request->name = talloc_strdup(request, c->module_name);