]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Check configuration in instantiate, before using it
authorAlan T. DeKok <aland@freeradius.org>
Sat, 7 Dec 2024 13:09:39 +0000 (08:09 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 7 Dec 2024 14:36:49 +0000 (09:36 -0500)
src/lib/bio/fd.h
src/lib/bio/fd_open.c
src/modules/rlm_radius2/rlm_radius.c

index e2a9d02dd3581ecce045d31155bf2aeda24ae570..9dc027d15298871dd9bdfac7e265e52bd9c5614e 100644 (file)
@@ -148,6 +148,8 @@ int         fr_bio_fd_connect_full(fr_bio_t *bio, fr_event_list_t *el,
 
 fr_bio_fd_info_t const *fr_bio_fd_info(fr_bio_t *bio) CC_HINT(nonnull);
 
+int            fr_bio_fd_check_config(fr_bio_fd_config_t const *cfg) CC_HINT(nonnull);
+
 int            fr_bio_fd_open(fr_bio_t *bio, fr_bio_fd_config_t const *cfg) CC_HINT(nonnull);
 
 int            fr_bio_fd_write_only(fr_bio_t *bio) CC_HINT(nonnull);
index 86cfd726a5f126ea50ba337bfc078b40df77870d..d08ff980580ae680fbd667c1bffd1ea85e170212 100644 (file)
@@ -719,6 +719,61 @@ static int fr_bio_fd_socket_bind(fr_bio_fd_t *my, fr_bio_fd_config_t const *cfg)
        return fr_bio_fd_socket_name(my);
 }
 
+/** Checks the configuration without modifying anything.
+ *
+ */
+int fr_bio_fd_check_config(fr_bio_fd_config_t const *cfg)
+{
+       /*
+        *      Sanitize the IP addresses.
+        *
+        */
+       switch (cfg->type) {
+       case FR_BIO_FD_CONNECTED:
+               /*
+                *      Ensure that we have a destination address.
+                */
+               if (cfg->dst_ipaddr.af == AF_UNSPEC) {
+                       fr_strerror_const("No destination IP address was specified");
+                       return -1;
+               }
+
+               if (!cfg->dst_port) {
+                       fr_strerror_const("No destination port was specified");
+                       return -1;
+               }
+
+               /*
+                *      The source IP has to be the same address family as the destination IP.
+                */
+               if ((cfg->src_ipaddr.af != AF_UNSPEC) && (cfg->src_ipaddr.af != cfg->dst_ipaddr.af)) {
+                       fr_strerror_printf("Source and destination IP addresses are not from the same IP address family");
+                       return -1;
+               }
+               break;
+
+       case FR_BIO_FD_UNCONNECTED:
+       case FR_BIO_FD_LISTEN:
+               if (cfg->src_ipaddr.af == AF_UNSPEC) {
+                       fr_strerror_const("No source IP address was specified");
+                       return -1;
+               }
+
+               if (!cfg->src_port) {
+                       fr_strerror_const("No source port was specified");
+                       return -1;
+               }
+               break;
+
+       case FR_BIO_FD_ACCEPTED:
+               fr_assert(cfg->src_ipaddr.af != AF_UNSPEC);
+               fr_assert(cfg->dst_ipaddr.af != AF_UNSPEC);
+               break;
+       }
+
+       return 0;
+}
+
 /** Opens a socket and updates sock->fd
  *
  *  If the socket is asynchronous, it also calls connect()
@@ -747,25 +802,14 @@ int fr_bio_fd_open(fr_bio_t *bio, fr_bio_fd_config_t const *cfg)
                my->info.socket.inet.src_port = cfg->src_port;
                my->info.socket.inet.dst_port = cfg->dst_port;
 
+               if (fr_bio_fd_check_config(cfg) < 0) return -1;
+
                /*
                 *      Sanitize the IP addresses.
                 *
                 */
                switch (cfg->type) {
                case FR_BIO_FD_CONNECTED:
-                       /*
-                        *      Ensure that we have a destination address.
-                        */
-                       if (my->info.socket.inet.dst_ipaddr.af == AF_UNSPEC) {
-                               fr_strerror_const("No destination IP address was specified");
-                               return -1;
-                       }
-
-                       if (!my->info.socket.inet.dst_port) {
-                               fr_strerror_const("No destination port was specified");
-                               return -1;
-                       }
-
                        /*
                         *      No source specified, just bootstrap it from the destination.
                         */
@@ -792,15 +836,7 @@ int fr_bio_fd_open(fr_bio_t *bio, fr_bio_fd_config_t const *cfg)
 
                case FR_BIO_FD_UNCONNECTED:
                case FR_BIO_FD_LISTEN:
-                       if (my->info.socket.inet.src_ipaddr.af == AF_UNSPEC) {
-                               fr_strerror_const("No source IP address was specified");
-                               return -1;
-                       }
-
-                       if (!my->info.socket.inet.src_port) {
-                               fr_strerror_const("No source port was specified");
-                               return -1;
-                       }
+                       fr_assert(my->info.socket.inet.src_ipaddr.af != AF_UNSPEC);
                        break;
 
                case FR_BIO_FD_ACCEPTED:
index 89a4343ffe8ca2a067c190f77bb0aa6116bd10c4..e2e916dfdb7ba399b8fa15e05def4469bb09069d 100644 (file)
@@ -477,6 +477,11 @@ static int mod_instantiate(module_inst_ctx_t const *mctx)
        inst->name = mctx->mi->name;
        inst->received_message_authenticator = talloc_zero(NULL, bool);         /* Allocated outside of inst to default protection */
 
+       if (fr_bio_fd_check_config(&inst->fd_config) < 0) {
+               cf_log_perr(conf, "Invalid configuration");
+               return -1;
+       }
+
        /*
         *      Clamp max_packet_size first before checking recv_buff and send_buff
         */