From fc6bce092efde7f8a70ce5daf3b0b2631d1bdc0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= Date: Thu, 30 Jul 2026 01:34:40 -0400 Subject: [PATCH] incusd/firewall/nftables: Fix template race in applyNftConfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clone the common table template per call rather than mutating the shared parse tree, which could corrupt rendered rules when two firewall operations ran concurrently. Signed-off-by: Stéphane Graber --- internal/server/firewall/drivers/drivers_nftables.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/internal/server/firewall/drivers/drivers_nftables.go b/internal/server/firewall/drivers/drivers_nftables.go index 91652f39b3..1a29b6e745 100644 --- a/internal/server/firewall/drivers/drivers_nftables.go +++ b/internal/server/firewall/drivers/drivers_nftables.go @@ -754,15 +754,21 @@ func (d Nftables) aclRuleToNftRules(hostNameQuoted string, rule ACLRule) ([]stri // applyNftConfig loads the specified config template and then applies it to the common template before sending to // the nft command to be atomically applied to the system. func (d Nftables) applyNftConfig(tpl *template.Template, tplFields map[string]any) error { + // Clone the common table template so concurrent callers don't share parse trees. + tables, err := nftablesCommonTable.Clone() + if err != nil { + return fmt.Errorf("Failed cloning common table template: %w", err) + } + // Load the specified template into the common template's parse tree under the nftableContentTemplate // name so that the nftableContentTemplate template can use it with the generic name. - _, err := nftablesCommonTable.AddParseTree(nftablesContentTemplate, tpl.Tree) + _, err = tables.AddParseTree(nftablesContentTemplate, tpl.Tree) if err != nil { return fmt.Errorf("Failed loading %q template: %w", tpl.Name(), err) } config := &strings.Builder{} - err = nftablesCommonTable.Execute(config, tplFields) + err = tables.Execute(config, tplFields) if err != nil { return fmt.Errorf("Failed running %q template: %w", tpl.Name(), err) }