]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
RADIUS client: Fix previous failover change
authorJouni Malinen <j@w1.fi>
Sat, 28 Feb 2015 18:52:08 +0000 (20:52 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 28 Feb 2015 18:52:08 +0000 (20:52 +0200)
Commit 347c55e216f22002246e378097a16ecb24b7c106 ('RADIUS client: Re-try
connection if socket is closed on retransmit') added a possibility of
executing RADIUS server failover change within
radius_client_retransmit() without taking into account that this
operation may end up freeing the pending message that is being
processed. This could result in use of freed memory. Avoid this by
checking whether any pending messages have been removed and if so, do
not try to retransmit the potentially freed message.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/radius/radius_client.c

index 95f18537a505f0b2db4a3179c90aae2b6f28fb85..76c76a6af8dfaa819a04b4024ef8ecaea518f031 100644 (file)
@@ -335,13 +335,18 @@ static int radius_client_retransmit(struct radius_client_data *radius,
        struct hostapd_radius_servers *conf = radius->conf;
        int s;
        struct wpabuf *buf;
+       size_t prev_num_msgs;
 
        if (entry->msg_type == RADIUS_ACCT ||
            entry->msg_type == RADIUS_ACCT_INTERIM) {
                if (radius->acct_sock < 0)
                        radius_client_init_acct(radius);
-               if (radius->acct_sock < 0 && conf->num_acct_servers > 1)
+               if (radius->acct_sock < 0 && conf->num_acct_servers > 1) {
+                       prev_num_msgs = radius->num_msgs;
                        radius_client_auth_failover(radius);
+                       if (prev_num_msgs != radius->num_msgs)
+                               return 0;
+               }
                s = radius->acct_sock;
                if (entry->attempts == 0)
                        conf->acct_server->requests++;
@@ -352,8 +357,12 @@ static int radius_client_retransmit(struct radius_client_data *radius,
        } else {
                if (radius->auth_sock < 0)
                        radius_client_init_auth(radius);
-               if (radius->auth_sock < 0 && conf->num_auth_servers > 1)
+               if (radius->auth_sock < 0 && conf->num_auth_servers > 1) {
+                       prev_num_msgs = radius->num_msgs;
                        radius_client_auth_failover(radius);
+                       if (prev_num_msgs != radius->num_msgs)
+                               return 0;
+               }
                s = radius->auth_sock;
                if (entry->attempts == 0)
                        conf->auth_server->requests++;