From: Vsevolod Stakhov Date: Thu, 20 Nov 2025 12:32:33 +0000 (+0000) Subject: [Fix] Prevent infinite loop in split_networks_into_chunks() X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dbd475241cea95ac942cb58328da438a287e7c0f;p=thirdparty%2Frspamd.git [Fix] Prevent infinite loop in split_networks_into_chunks() If a single IP network entry exceeds max_record_length (450 chars) on its own, the code would enter an infinite loop. Added validation to check if individual items can fit before attempting to add them to chunks. Items that are too large are now skipped with a warning message. --- diff --git a/lualib/rspamadm/dns_tool.lua b/lualib/rspamadm/dns_tool.lua index cabc6aa75a..e6da7a251c 100644 --- a/lualib/rspamadm/dns_tool.lua +++ b/lualib/rspamadm/dns_tool.lua @@ -385,22 +385,32 @@ local function spf_flatten_handler(opts) end for _, item in ipairs(all_v4) do - table.insert(current_chunk_v4, item) - local test_record = build_spf_record(current_chunk_v4, current_chunk_v6, {}, all_mechs, nil) - if #test_record > max_record_length then - table.remove(current_chunk_v4) - finalize_chunk() + local single_item_test = build_spf_record({item}, {}, {}, all_mechs, nil) + if #single_item_test > max_record_length then + printf('Warning: IPv4 network %s is too large to fit in a single SPF record, skipping', item.net) + else table.insert(current_chunk_v4, item) + local test_record = build_spf_record(current_chunk_v4, current_chunk_v6, {}, all_mechs, nil) + if #test_record > max_record_length then + table.remove(current_chunk_v4) + finalize_chunk() + table.insert(current_chunk_v4, item) + end end end for _, item in ipairs(all_v6) do - table.insert(current_chunk_v6, item) - local test_record = build_spf_record(current_chunk_v4, current_chunk_v6, {}, all_mechs, nil) - if #test_record > max_record_length then - table.remove(current_chunk_v6) - finalize_chunk() + local single_item_test = build_spf_record({}, {item}, {}, all_mechs, nil) + if #single_item_test > max_record_length then + printf('Warning: IPv6 network %s is too large to fit in a single SPF record, skipping', item.net) + else table.insert(current_chunk_v6, item) + local test_record = build_spf_record(current_chunk_v4, current_chunk_v6, {}, all_mechs, nil) + if #test_record > max_record_length then + table.remove(current_chunk_v6) + finalize_chunk() + table.insert(current_chunk_v6, item) + end end end