| From 339a334551ca911187cc870f4f97ef08e11db109 Mon Sep 17 00:00:00 2001 |
| From: Jouni Malinen <quic_jouni@quicinc.com> |
| Date: Wed, 5 Feb 2025 19:23:39 +0200 |
| Subject: 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") |
| |
| Upstream: https://git.w1.fi/cgit/hostap/commit/?id=339a334551ca911187cc870f4f97ef08e11db109 |
| CVE: CVE-2025-24912 |
| |
| Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com> |
| Signed-off-by: Titouan Christophe <titouan.christophe@mind.be> |
| --- |
| src/radius/radius_client.c | 10 +++++++--- |
| 1 file changed, 7 insertions(+), 3 deletions(-) |
| |
| 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 |
| -- |
| cgit v1.2.3 |
| |