From: Vsevolod Stakhov Date: Mon, 12 Jan 2026 16:25:30 +0000 (+0000) Subject: [Fix] Reduce control message size to prevent sendmsg crash X-Git-Tag: 4.0.0~202 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=66db7f40b2f90e30213adf636d93fba2fc479b14;p=thirdparty%2Frspamd.git [Fix] Reduce control message size to prevent sendmsg crash 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 --- diff --git a/src/hs_helper.c b/src/hs_helper.c index 2607d8f414..9b8821332f 100644 --- a/src/hs_helper.c +++ b/src/hs_helper.c @@ -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); diff --git a/src/libserver/rspamd_control.c b/src/libserver/rspamd_control.c index 586774ff5b..47c797ea09 100644 --- a/src/libserver/rspamd_control.c +++ b/src/libserver/rspamd_control.c @@ -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 diff --git a/src/libserver/rspamd_control.h b/src/libserver/rspamd_control.h index d68a138755..6b1835c609 100644 --- a/src/libserver/rspamd_control.h +++ b/src/libserver/rspamd_control.h @@ -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; diff --git a/src/libserver/worker_util.c b/src/libserver/worker_util.c index 4a06018af4..9aa68a96a6 100644 --- a/src/libserver/worker_util.c +++ b/src/libserver/worker_util.c @@ -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);