From: Jouni Malinen Date: Wed, 5 Feb 2025 17:23:39 +0000 (+0200) Subject: RADIUS: Fix pending request dropping X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=339a334551ca911187cc870f4f97ef08e11db109;p=thirdparty%2Fhostap.git RADIUS: Fix pending request dropping A recent change to this moved the place where the processed RADIUS request was removed from the pending list to happen after the message handler had been called. This did not take into account possibility of the handler adding a new pending request in the list and the prev_req pointer not necessarily pointing to the correct entry anymore. As such, some of the pending requests could have been lost and that would result in not being able to process responses to those requests and also, to a memory leak. Fix this by determining prev_req at the point when the pending request is being removed, i.e., after the handler function has already added a new entry. Fixes: 726432d7622c ("RADIUS: Drop pending request only when accepting the response") Signed-off-by: Jouni Malinen --- diff --git a/src/radius/radius_client.c b/src/radius/radius_client.c index 7909b29a7..d4faa7936 100644 --- a/src/radius/radius_client.c +++ b/src/radius/radius_client.c @@ -1099,7 +1099,7 @@ static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx) struct radius_hdr *hdr; struct radius_rx_handler *handlers; size_t num_handlers, i; - struct radius_msg_list *req, *prev_req; + struct radius_msg_list *req, *prev_req, *r; struct os_reltime now; struct hostapd_radius_server *rconf; int invalid_authenticator = 0; @@ -1224,7 +1224,6 @@ static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx) break; } - prev_req = NULL; req = radius->msgs; while (req) { /* TODO: also match by src addr:port of the packet when using @@ -1236,7 +1235,6 @@ static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx) hdr->identifier) break; - prev_req = req; req = req->next; } @@ -1270,6 +1268,12 @@ static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx) /* fall through */ case RADIUS_RX_QUEUED: /* Remove ACKed RADIUS packet from retransmit list */ + prev_req = NULL; + for (r = radius->msgs; r; r = r->next) { + if (r == req) + break; + prev_req = r; + } if (prev_req) prev_req->next = req->next; else