]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] Reduce control message size to prevent sendmsg crash
authorVsevolod Stakhov <vsevolod@rspamd.com>
Mon, 12 Jan 2026 16:25:30 +0000 (16:25 +0000)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Mon, 12 Jan 2026 16:25:30 +0000 (16:25 +0000)
The rspamd_srv_command and rspamd_control_command structures grew too
large (~8KB) due to multiple CONTROL_PATHLEN fields in mp_loaded and
re_map_loaded, exceeding socket buffer limits and causing crashes in
sendmsg during worker startup.

Fix by:
- Removing redundant cache_dir fields (all processes know it from config)
- Using consistent name[64] for both mp_loaded and re_map_loaded
- Getting cache_dir from cfg->hs_cache_dir at receive time instead

src/hs_helper.c
src/libserver/rspamd_control.c
src/libserver/rspamd_control.h
src/libserver/worker_util.c

index 2607d8f414ed5f8c3a894e1c74ff1a50ffb54f45..9b8821332f4bdb314c22eaf4dbe4ad769b2e3db6 100644 (file)
@@ -830,8 +830,6 @@ rspamd_hs_helper_mp_send_notification(struct hs_helper_ctx *ctx,
        srv_cmd.type = RSPAMD_SRV_MULTIPATTERN_LOADED;
        rspamd_strlcpy(srv_cmd.cmd.mp_loaded.name, name,
                                   sizeof(srv_cmd.cmd.mp_loaded.name));
-       rspamd_strlcpy(srv_cmd.cmd.mp_loaded.cache_dir, ctx->hs_dir,
-                                  sizeof(srv_cmd.cmd.mp_loaded.cache_dir));
 
        rspamd_srv_send_command(worker, ctx->event_loop, &srv_cmd, -1, NULL, NULL);
        msg_debug_hyperscan("sent multipattern loaded notification for '%s'", name);
@@ -997,8 +995,6 @@ rspamd_hs_helper_remap_send_notification(struct hs_helper_ctx *ctx,
        srv_cmd.type = RSPAMD_SRV_REGEXP_MAP_LOADED;
        rspamd_strlcpy(srv_cmd.cmd.re_map_loaded.name, name,
                                   sizeof(srv_cmd.cmd.re_map_loaded.name));
-       rspamd_strlcpy(srv_cmd.cmd.re_map_loaded.cache_dir, ctx->hs_dir,
-                                  sizeof(srv_cmd.cmd.re_map_loaded.cache_dir));
 
        rspamd_srv_send_command(worker, ctx->event_loop, &srv_cmd, -1, NULL, NULL);
        msg_debug_hyperscan("sent regexp map loaded notification for '%s'", name);
index 586774ff5b3dcea1667320b72e30f80aa99774be..47c797ea096d9c69bb5bb3e7f3fae732759585bf 100644 (file)
@@ -1161,8 +1161,8 @@ rspamd_srv_handler(EV_P_ ev_io *w, int revents)
                                break;
                        case RSPAMD_SRV_MULTIPATTERN_LOADED:
 #ifdef WITH_HYPERSCAN
-                               msg_info_main("received multipattern loaded notification for '%s' from %s",
-                                                         cmd.cmd.mp_loaded.name, cmd.cmd.mp_loaded.cache_dir);
+                               msg_info_main("received multipattern loaded notification for '%s'",
+                                                         cmd.cmd.mp_loaded.name);
 
                                /* Broadcast command to all workers */
                                memset(&wcmd, 0, sizeof(wcmd));
@@ -1170,17 +1170,14 @@ rspamd_srv_handler(EV_P_ ev_io *w, int revents)
                                rspamd_strlcpy(wcmd.cmd.mp_loaded.name,
                                                           cmd.cmd.mp_loaded.name,
                                                           sizeof(wcmd.cmd.mp_loaded.name));
-                               rspamd_strlcpy(wcmd.cmd.mp_loaded.cache_dir,
-                                                          cmd.cmd.mp_loaded.cache_dir,
-                                                          sizeof(wcmd.cmd.mp_loaded.cache_dir));
                                rspamd_control_broadcast_cmd(rspamd_main, &wcmd, rfd,
                                                                                         rspamd_control_ignore_io_handler, NULL, worker->pid);
 #endif
                                break;
                        case RSPAMD_SRV_REGEXP_MAP_LOADED:
 #ifdef WITH_HYPERSCAN
-                               msg_info_main("received regexp map loaded notification for '%s' from %s",
-                                                         cmd.cmd.re_map_loaded.name, cmd.cmd.re_map_loaded.cache_dir);
+                               msg_info_main("received regexp map loaded notification for '%s'",
+                                                         cmd.cmd.re_map_loaded.name);
 
                                /* Broadcast command to all workers */
                                memset(&wcmd, 0, sizeof(wcmd));
@@ -1188,9 +1185,6 @@ rspamd_srv_handler(EV_P_ ev_io *w, int revents)
                                rspamd_strlcpy(wcmd.cmd.re_map_loaded.name,
                                                           cmd.cmd.re_map_loaded.name,
                                                           sizeof(wcmd.cmd.re_map_loaded.name));
-                               rspamd_strlcpy(wcmd.cmd.re_map_loaded.cache_dir,
-                                                          cmd.cmd.re_map_loaded.cache_dir,
-                                                          sizeof(wcmd.cmd.re_map_loaded.cache_dir));
                                rspamd_control_broadcast_cmd(rspamd_main, &wcmd, rfd,
                                                                                         rspamd_control_ignore_io_handler, NULL, worker->pid);
 #endif
index d68a1387559f37bba552de8639f47f51667417c5..6b1835c6097e3d8ef957823b108356df1a8ad1d4 100644 (file)
@@ -86,11 +86,9 @@ struct rspamd_control_command {
                } hs_loaded;
                struct {
                        char name[64];
-                       char cache_dir[CONTROL_PATHLEN];
                } mp_loaded;
                struct {
-                       char name[CONTROL_PATHLEN]; /* Map name */
-                       char cache_dir[CONTROL_PATHLEN];
+                       char name[64]; /* Map name */
                } re_map_loaded;
                struct {
                        char tag[32];
@@ -244,12 +242,10 @@ struct rspamd_srv_command {
                /* Sent when a multipattern hyperscan db is compiled */
                struct {
                        char name[64];
-                       char cache_dir[CONTROL_PATHLEN];
                } mp_loaded;
                /* Sent when a regexp map hyperscan db is compiled */
                struct {
-                       char name[CONTROL_PATHLEN]; /* Map name */
-                       char cache_dir[CONTROL_PATHLEN];
+                       char name[64]; /* Map name */
                } re_map_loaded;
                struct {
                        gboolean is_busy;
index 4a06018af47be2a93a8e001a2cca366107c302d6..9aa68a96a6eaebd097c7098d72c6d7c058431363 100644 (file)
@@ -2107,13 +2107,12 @@ rspamd_worker_multipattern_ready(struct rspamd_main *rspamd_main,
        struct rspamd_control_reply rep;
        struct rspamd_multipattern *mp;
        const char *name = cmd->cmd.mp_loaded.name;
-       const char *cache_dir = cmd->cmd.mp_loaded.cache_dir;
+       const char *cache_dir = worker->srv->cfg->hs_cache_dir;
 
        memset(&rep, 0, sizeof(rep));
        rep.type = RSPAMD_CONTROL_MULTIPATTERN_LOADED;
 
-       msg_debug_hyperscan("received multipattern loaded notification for '%s', cache_dir=%s",
-                                               name, cache_dir);
+       msg_debug_hyperscan("received multipattern loaded notification for '%s'", name);
 
        mp = rspamd_multipattern_find_pending(name);
 
@@ -2191,13 +2190,12 @@ rspamd_worker_regexp_map_ready(struct rspamd_main *rspamd_main,
        struct rspamd_control_reply rep;
        struct rspamd_regexp_map_helper *re_map;
        const char *name = cmd->cmd.re_map_loaded.name;
-       const char *cache_dir = cmd->cmd.re_map_loaded.cache_dir;
+       const char *cache_dir = worker->srv->cfg->hs_cache_dir;
 
        memset(&rep, 0, sizeof(rep));
        rep.type = RSPAMD_CONTROL_REGEXP_MAP_LOADED;
 
-       msg_debug_hyperscan("received regexp map loaded notification for '%s', cache_dir=%s",
-                                               name, cache_dir);
+       msg_debug_hyperscan("received regexp map loaded notification for '%s'", name);
 
        re_map = rspamd_regexp_map_find_pending(name);