]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Fixes to get listeners to work with mprotect
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 13 May 2024 00:06:05 +0000 (18:06 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 13 May 2024 13:42:22 +0000 (07:42 -0600)
17 files changed:
src/lib/io/master.c
src/lib/io/master.h
src/lib/server/module.c
src/lib/server/module.h
src/lib/server/virtual_servers.c
src/listen/bfd/proto_bfd.c
src/listen/control/proto_control.c
src/listen/cron/proto_cron.c
src/listen/detail/proto_detail.c
src/listen/dhcpv4/proto_dhcpv4.c
src/listen/dhcpv6/proto_dhcpv6.c
src/listen/dns/proto_dns.c
src/listen/load/proto_load.c
src/listen/radius/proto_radius.c
src/listen/radius/proto_radius_udp.c
src/listen/tacacs/proto_tacacs.c
src/listen/vmps/proto_vmps.c

index 42d6cc30c915e39282c4513a338b9c4f5387dd8d..3a090be5cdb2e5715ff163c1ae89842f6994b1fc 100644 (file)
@@ -2908,7 +2908,7 @@ int fr_io_listen_free(fr_listen_t *li)
        return 0;
 }
 
-int fr_master_io_listen(TALLOC_CTX *ctx, fr_io_instance_t *inst, fr_schedule_t *sc,
+int fr_master_io_listen(fr_io_instance_t *inst, fr_schedule_t *sc,
                        size_t default_message_size, size_t num_messages)
 {
        fr_listen_t     *li, *child;
index fef64cb3c91e947e03bf0249fc4a50ed0d0c0866..dcd57485c420f7946e54c6af239ef04135712617 100644 (file)
@@ -105,7 +105,7 @@ typedef struct {
 extern fr_app_io_t fr_master_app_io;
 
 fr_trie_t *fr_master_io_network(TALLOC_CTX *ctx, int af, fr_ipaddr_t *allow, fr_ipaddr_t *deny);
-int fr_master_io_listen(TALLOC_CTX *ctx, fr_io_instance_t *io, fr_schedule_t *sc,
+int fr_master_io_listen(fr_io_instance_t *io, fr_schedule_t *sc,
                        size_t default_message_size, size_t num_messages) CC_HINT(nonnull);
 fr_io_track_t *fr_master_io_track_alloc(fr_listen_t *li, fr_client_t *client, fr_ipaddr_t const *src_ipaddr, int src_port,
                                        fr_ipaddr_t const *dst_ipaddr, int dst_port);
index 8119f647f3e4ba01d8062d3a1695143f255ace90..3c4a30f514d45b6dfd360841c898dbefd4357f48 100644 (file)
@@ -638,12 +638,12 @@ int module_data_protect(module_instance_t *mi, module_data_pool_t *pool)
        if (pool->start == NULL) return 0; /* noop */
 
        DEBUG("Protecting data %s %p-%p", mi->name, pool->start, (uint8_t *)pool->start + pool->len);
-#if 0
+
        if (unlikely(mprotect(pool->start, pool->len, PROT_READ) < 0)) {
                fr_strerror_printf("Protecting \"%s\" module data failed: %s", mi->name, fr_syserror(errno));
                return -1;
        }
-#endif
+
        return 0;
 }
 
@@ -655,20 +655,44 @@ int module_data_protect(module_instance_t *mi, module_data_pool_t *pool)
  *     - -1 on failure.
  */
 static inline CC_HINT(always_inline)
-int module_data_unprotect(module_instance_t *mi, module_data_pool_t *pool)
+int module_data_unprotect(module_instance_t const *mi, module_data_pool_t const *pool)
 {
        if (pool->start == NULL) return 0; /* noop */
 
        DEBUG("Unprotecting data %s %p-%p", mi->name, pool->start, (uint8_t *)pool->start + pool->len);
-#if 0
+
        if (unlikely(mprotect(pool->start, pool->len, PROT_READ | PROT_WRITE) < 0)) {
                fr_strerror_printf("Unprotecting \"%s\" data failed: %s", mi->name, fr_syserror(errno));
                return -1;
        }
-#endif
+
        return 0;
 }
 
+/** Mark module data as read only
+ *
+ * @param[in] mi       Instance data to protect (mark as read only).
+ * @return
+ *     - 0 on success.
+ *     - -1 on failure.
+ */
+int module_instance_data_protect(module_instance_t const *mi)
+{
+       return module_data_unprotect(mi, &mi->inst_pool);
+}
+
+/** Mark module data as read/write
+ *
+ * @param[in] mi       Instance data to unprotect (mark as read/write).
+ * @return
+ *     - 0 on success.
+ *     - -1 on failure.
+ */
+int module_instance_data_unprotect(module_instance_t const *mi)
+{
+       return module_data_unprotect(mi, &mi->inst_pool);
+}
+
 /** Return the prefix string for the deepest module
  *
  * This is useful for submodules which don't have a prefix of their own.
index 99e69c96be2dfff6823e09b3b3ccc5bfb272e74d..41d9ec42bb2e78e4b47939e6bd5bfcb504adaced 100644 (file)
@@ -388,6 +388,19 @@ void module_instance_debug(module_instance_t const *mi) CC_HINT(nonnull);
 void module_list_debug(module_list_t const *ml) CC_HINT(nonnull);
  /** @} */
 
+/** @name Toggle protection on module instance data
+ *
+ * This is used for module lists which implement additional instantiation phases
+ * (like li->open).  It should NOT be used by modules to hack around instance
+ * data being read-only after instantiation completes.
+ *
+ * @{
+ */
+int                    module_instance_data_protect(module_instance_t const *mi);
+
+int                    module_instance_data_unprotect(module_instance_t const *mi);
+ /** @} */
+
 /** @name Module and module thread lookup
  *
  * @{
index de919617b3348a0093de8719167d36e1e7121222..c63cc65c6bd88214e768501eb839f64ae487d015 100644 (file)
@@ -1392,13 +1392,25 @@ int virtual_servers_open(fr_schedule_t *sc)
                         *      Even then, proto_radius usually calls fr_master_io_listen() in order
                         *      to create the fr_listen_t structure.
                         */
-                       if (listener->proto_module->open &&
-                           listener->proto_module->open(listener->proto_mi->data, sc,
-                                                        listener->proto_mi->conf) < 0) {
-                               cf_log_err(listener->proto_mi->conf,
-                                          "Opening %s I/O interface failed",
-                                          listener->proto_module->common.name);
-                               return -1;
+                       if (listener->proto_module->open) {
+                               int ret;
+
+                               /*
+                                *      Sometimes the open function needs to modify instance
+                                *      data, so we need to temporarily remove the protection.
+                                */
+                               module_instance_data_unprotect(listener->proto_mi);
+                               ret = listener->proto_module->open(listener->proto_mi->data, sc,
+                                                                  listener->proto_mi->conf);
+                               module_instance_data_protect(listener->proto_mi);
+                               if (unlikely(ret < 0)) {
+                                       cf_log_err(listener->proto_mi->conf,
+                                                  "Opening %s I/O interface failed",
+                                                  listener->proto_module->common.name);
+
+                                       return -1;
+                               }
+
                        }
 
                        /*
index e4e609d171897ffa4ec064551f8b8bdd7500eab4..0a38eead00a20734787ea01b13f4ce98f84cd647 100644 (file)
@@ -303,7 +303,7 @@ static int mod_open(void *instance, fr_schedule_t *sc, UNUSED CONF_SECTION *conf
        /*
         *      io.app_io should already be set
         */
-       return fr_master_io_listen(inst, &inst->io, sc,
+       return fr_master_io_listen(&inst->io, sc,
                                   inst->max_packet_size, inst->num_messages);
 }
 
index 25816f62839f6a6d8417b0e73d0a284243353a07..4a9019c0e69ac6f52ea9d701bedf0594353bf613 100644 (file)
@@ -80,7 +80,7 @@ static int mod_open(void *instance, fr_schedule_t *sc, UNUSED CONF_SECTION *conf
        inst->io.app = &proto_control;
        inst->io.app_instance = instance;
 
-       return fr_master_io_listen(inst, &inst->io, sc,
+       return fr_master_io_listen(&inst->io, sc,
                                   inst->max_packet_size, inst->num_messages);
 }
 
index 05f5c7c9490c830f6ae2c19a77b6980b2d6cc991..7b911c831f847ef8cbbf962b04c86c9fe2161283 100644 (file)
@@ -161,7 +161,7 @@ static int mod_open(void *instance, fr_schedule_t *sc, UNUSED CONF_SECTION *conf
        /*
         *      io.app_io should already be set
         */
-       return fr_master_io_listen(inst, &inst->io, sc,
+       return fr_master_io_listen(&inst->io, sc,
                                   inst->max_packet_size, inst->num_messages);
 }
 
index 0b205159b5aee9793df514c8665f77e0dda49be0..cbef9ff4eaf09afa7cbd3105f5f1827607413b1d 100644 (file)
@@ -436,11 +436,11 @@ static int mod_open(void *instance, fr_schedule_t *sc, CONF_SECTION *conf)
         *      path, data takes from the socket to the decoder and
         *      back again.
         */
-       li = talloc_zero(inst, fr_listen_t);
+       MEM(li = talloc_zero(NULL, fr_listen_t));       /* Assigned thread steals the memory */
        talloc_set_destructor(li, fr_io_listen_free);
 
        li->app_io = inst->app_io;
-       li->thread_instance = talloc_zero_array(NULL, uint8_t, li->app_io->common.thread_inst_size);
+       li->thread_instance = talloc_zero_array(li, uint8_t, li->app_io->common.thread_inst_size);
        talloc_set_name(li->thread_instance, "proto_%s_thread_t", inst->app_io->common.name);
        li->app_io_instance = inst->app_io_instance;
 
index 10e9900af76f1fc81780984e60d4e16281662904..0d425f3ec0dc60924056f4034332fd226cbab1a0 100644 (file)
@@ -349,7 +349,7 @@ static int mod_open(void *instance, fr_schedule_t *sc, UNUSED CONF_SECTION *conf
        inst->io.app = &proto_dhcpv4;
        inst->io.app_instance = instance;
 
-       return fr_master_io_listen(inst, &inst->io, sc,
+       return fr_master_io_listen(&inst->io, sc,
                                   inst->max_packet_size, inst->num_messages);
 }
 
index e000980eb9b7301771c1d9f74ca15d181a50d35d..172e226f423566c5204159a7294fb82458d115e6 100644 (file)
@@ -330,7 +330,7 @@ static int mod_open(void *instance, fr_schedule_t *sc, UNUSED CONF_SECTION *conf
        inst->io.app = &proto_dhcpv6;
        inst->io.app_instance = instance;
 
-       return fr_master_io_listen(inst, &inst->io, sc,
+       return fr_master_io_listen(&inst->io, sc,
                                   inst->max_packet_size, inst->num_messages);
 }
 
index 00885468edb5169d9490d06e82aaad0194158b3f..b589c32b65e07681daf101bc17cf219fb96bd039 100644 (file)
@@ -279,7 +279,7 @@ static int mod_open(void *instance, fr_schedule_t *sc, UNUSED CONF_SECTION *conf
        inst->io.app = &proto_dns;
        inst->io.app_instance = instance;
 
-       return fr_master_io_listen(inst, &inst->io, sc,
+       return fr_master_io_listen(&inst->io, sc,
                                   inst->max_packet_size, inst->num_messages);
 }
 
index fc43f3bf1e102f12c2914a140f59d448ab3c9f6e..386053157aaa365b055bc16626840ee3e15a6207 100644 (file)
@@ -171,7 +171,7 @@ static int mod_open(void *instance, fr_schedule_t *sc, UNUSED CONF_SECTION *conf
        /*
         *      io.app_io should already be set
         */
-       return fr_master_io_listen(inst, &inst->io, sc,
+       return fr_master_io_listen(&inst->io, sc,
                                   inst->max_packet_size, inst->num_messages);
 }
 
index 488f1f362cff348c3c9c8b9aae3086e773a952a3..e582281d94ec287f523ba6b0833794a80eda5622 100644 (file)
@@ -418,7 +418,7 @@ static int mod_open(void *instance, fr_schedule_t *sc, UNUSED CONF_SECTION *conf
        /*
         *      io.app_io should already be set
         */
-       return fr_master_io_listen(inst, &inst->io, sc,
+       return fr_master_io_listen(&inst->io, sc,
                                   inst->max_packet_size, inst->num_messages);
 }
 
index a7f948ba9a93856895fbb694b26e45e912e3caf6..ea9cc9e7c0af90c8e066f35d6b3204e426cfb7e2 100644 (file)
@@ -176,7 +176,7 @@ static ssize_t mod_read(fr_listen_t *li, void **packet_ctx, fr_time_t *recv_time
                /*
                 *      @todo - check for F5 load balancer packets.  <sigh>
                 */
-               DEBUG2("proto_radius_udp got a packet which isn't RADIUS");
+               DEBUG2("proto_radius_udp got a packet which isn't RADIUS: %s", fr_strerror());
                thread->stats.total_malformed_requests++;
                return 0;
        }
index bec40e3e91707e47927f73ce934ee6cfad04d656..b2eea3208eaa35406994980e9b0ca871400a9801 100644 (file)
@@ -437,7 +437,7 @@ static int mod_open(void *instance, fr_schedule_t *sc, UNUSED CONF_SECTION *conf
        /*
         *      io.app_io should already be set
         */
-       return fr_master_io_listen(inst, &inst->io, sc, inst->max_packet_size, inst->num_messages);
+       return fr_master_io_listen(&inst->io, sc, inst->max_packet_size, inst->num_messages);
 }
 
 /** Instantiate the application
index 086e16264fa82099dec9701a8649187a95f75fc1..c57663fad7f0e815afdeb280aa056d32285d20ae 100644 (file)
@@ -298,7 +298,7 @@ static int mod_open(void *instance, fr_schedule_t *sc, UNUSED CONF_SECTION *conf
        inst->io.app = &proto_vmps;
        inst->io.app_instance = instance;
 
-       return fr_master_io_listen(inst, &inst->io, sc,
+       return fr_master_io_listen(&inst->io, sc,
                                   inst->max_packet_size, inst->num_messages);
 }