]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Look up in client tree, even if we have a cached entry. Fixes #5676
authorShang Chieh Tseng <shangchieh.tseng@tsengsyu.com>
Wed, 1 Apr 2026 15:25:32 +0000 (11:25 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Wed, 1 Apr 2026 15:33:18 +0000 (11:33 -0400)
When the per-thread client trie has a cached entry from a broad
subnet (e.g. /8), it shadows more specific client definitions
(e.g. /24) for subsequent connections.  This causes the wrong
shared secret to be used, breaking packet authentication (RADIUS)
or decryption (TACACS+).

After the trie lookup returns a cached client, verify it against
the global client list.  If a more specific match exists, discard
the cached result so the existing code path does a fresh lookup
and caches the correct client.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
src/lib/io/master.c

index d086eae2cbb722dad9f4ac42d7f2c2b574b4ee3e..9f23eaa1ad502f7585eb3a8cf5a7f08422e655c6 100644 (file)
@@ -1568,6 +1568,21 @@ do_read:
                                        &address.socket.inet.src_ipaddr.addr, address.socket.inet.src_ipaddr.prefix);
                fr_assert(!client || !client->connection);
 
+               /*
+                *      Verify the cached client is the most specific match.
+                *      A broader subnet may have been cached first, shadowing
+                *      a more specific client definition.
+                */
+               if (client && (client->state == PR_CLIENT_STATIC)) {
+                       fr_client_t *radclient;
+
+                       radclient = inst->app_io->client_find(thread->child,
+                                                             &address.socket.inet.src_ipaddr, inst->ipproto);
+                       if (radclient && (radclient->ipaddr.prefix > client->src_ipaddr.prefix)) {
+                               client = NULL;
+                       }
+               }
+
        } else {
                client = connection->client;