From bce6db6c3c208191e8c1962e3ded0dbfc015d052 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Fri, 29 Oct 2021 10:38:15 +0200 Subject: [PATCH] BUG/MEDIUM: resolvers: Don't recursively perform requester unlink When a requester is unlink from a resolution, by reading the code, we can have this call chain: _resolv_unlink_resolution(srv->resolv_requester) resolv_detach_from_resolution_answer_items(resolution, requester) resolv_srvrq_cleanup_srv(srv) _resolv_unlink_resolution(srv->resolv_requester) A loop on the resolution answer items is performed inside resolv_detach_from_resolution_answer_items(). But by reading the code, it seems possible to recursively unlink the same requester. To avoid any loop at this stage, the requester clean up must be performed before the call to resolv_detach_from_resolution_answer_items(). This way, the second call to _resolv_unlink_resolution() does nothing and returns immediately because the requester was already detached from the resolution. This patch is related to the issue #1404. It must be backported as far as 2.2. --- src/resolvers.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/resolvers.c b/src/resolvers.c index a806f3397d..5ed866b086 100644 --- a/src/resolvers.c +++ b/src/resolvers.c @@ -2079,13 +2079,13 @@ static void _resolv_unlink_resolution(struct resolv_requester *requester) return; res = requester->resolution; - /* remove ref from the resolution answer item list to the requester */ - resolv_detach_from_resolution_answer_items(res, requester); - /* Clean up the requester */ LIST_DEL_INIT(&requester->list); requester->resolution = NULL; + /* remove ref from the resolution answer item list to the requester */ + resolv_detach_from_resolution_answer_items(res, requester); + /* We need to find another requester linked on this resolution */ if (!LIST_ISEMPTY(&res->requesters)) req = LIST_NEXT(&res->requesters, struct resolv_requester *, list); -- 2.47.3