VYPR
Low severity3.4OSV Advisory· Published Jun 25, 2025· Updated Apr 15, 2026

CVE-2025-52889

CVE-2025-52889

Description

Incus is a system container and virtual machine manager. When using an ACL on a device connected to a bridge, Incus version 6.12 and 6.13 generates nftables rules for local services (DHCP, DNS...) that partially bypass security options security.mac_filtering, security.ipv4_filtering and security.ipv6_filtering. This can lead to DHCP pool exhaustion and opens the door for other attacks. A patch is available at commit 2516fb19ad8428454cb4edfe70c0a5f0dc1da214.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/lxc/incus/v6Go
< 6.14.06.14.0

Affected products

1
  • Range: v0.1.0, v0.2.0, v0.3.0, …

Patches

2
2516fb19ad84

incusd/firewall/nftables: Fix ordering of basic rules

https://github.com/lxc/incusOlivier Bal-PetreJun 2, 2025via ghsa
1 file changed · +24 25
  • internal/server/firewall/drivers/drivers_nftables_templates.go+24 25 modified
    @@ -192,38 +192,19 @@ var nftablesInstanceBridgeFilter = template.Must(template.New("nftablesInstanceB
     chain in{{.chainSeparator}}{{.deviceLabel}} {
     	type filter hook input priority -200; policy accept;
     
    -	# Basic connectivity
    -	{{ if or .aclInDropRules .aclInRejectRules .aclInAcceptRules .aclOutDropRules .aclOutAcceptRules .aclInDefaultRule }}
    -
    -	{{ if .dnsIPv4 }}
    -	{{ range .dnsIPv4 }}
    -	iifname "{{$.hostName}}" ip daddr "{{.}}" tcp dport 53 accept
    -	iifname "{{$.hostName}}" ip daddr "{{.}}" udp dport 53 accept
    -	{{ end }}
    -	{{ end }}
    -
    -	{{ if .dnsIPv6 }}
    -	{{ range .dnsIPv6 }}
    -	iifname "{{$.hostName}}" ip6 daddr "{{.}}" tcp dport 53 accept
    -	iifname "{{$.hostName}}" ip6 daddr "{{.}}" udp dport 53 accept
    -	{{ end }}
    -	{{ end }}
    -
    -	iifname "{{.hostName}}" ether type ip ip saddr 0.0.0.0 ip daddr 255.255.255.255 udp dport 67 accept
    -	iifname "{{.hostName}}" ether type ip6 ip6 saddr fe80::/10 ip6 daddr ff02::1:2 udp dport 547 accept
    -	iifname "{{.hostName}}" ether type ip6 ip6 saddr fe80::/10 ip6 daddr ff02::2 icmpv6 type 133 accept
    -	{{ end }}
    -
     	# MAC filtering
     	{{ if .macFiltering }}
     	iifname "{{.hostName}}" ether saddr != {{.hwAddr}} drop
     	iifname "{{.hostName}}" ether type arp arp saddr ether != {{.hwAddr}} drop
     	iifname "{{.hostName}}" ether type ip6 icmpv6 type 136 @nh,528,48 != {{.hwAddrHex}} drop
     	{{ end }}
     
    +	{{ if or .aclInDropRules .aclInRejectRules .aclInAcceptRules .aclOutDropRules .aclOutAcceptRules .aclInDefaultRule .ipv4NetsList }}
    +	iifname "{{.hostName}}" ether type ip ip saddr 0.0.0.0 ip daddr 255.255.255.255 udp dport 67 accept
    +	{{ end }}
    +
     	# IPv4 filtering
     	{{ if .ipv4NetsList }}
    -	iifname "{{.hostName}}" ether type ip ip saddr 0.0.0.0 ip daddr 255.255.255.255 udp dport 67 accept
     	iifname "{{.hostName}}" ether type arp arp saddr ip != { {{.ipv4NetsList}} } drop
     	iifname "{{.hostName}}" ether type ip ip saddr != { {{.ipv4NetsList}} } drop
     	{{ end }}
    @@ -232,10 +213,13 @@ chain in{{.chainSeparator}}{{.deviceLabel}} {
     	iifname "{{.hostName}}" ether type ip drop
     	{{ end }}
     
    -	# IPv6 filtering
    -	{{ if .ipv6NetsList }}
    +	{{ if or .aclInDropRules .aclInRejectRules .aclInAcceptRules .aclOutDropRules .aclOutAcceptRules .aclInDefaultRule .ipv6NetsList }}
     	iifname "{{.hostName}}" ether type ip6 ip6 saddr fe80::/10 ip6 daddr ff02::1:2 udp dport 547 accept
     	iifname "{{.hostName}}" ether type ip6 ip6 saddr fe80::/10 ip6 daddr ff02::2 icmpv6 type 133 accept
    +	{{ end }}
    +
    +	# IPv6 filtering
    +	{{ if .ipv6NetsList }}
     	iifname "{{.hostName}}" ether type ip6 icmpv6 type 134 drop
     	iifname "{{.hostName}}" ether type ip6 icmpv6 type 136 {{.ipv6NetsPrefixList}} drop
     	iifname "{{.hostName}}" ether type ip6 ip6 saddr != { {{.ipv6NetsList}} } drop
    @@ -249,6 +233,21 @@ chain in{{.chainSeparator}}{{.deviceLabel}} {
     
     	iifname "{{.hostName}}" ether type arp accept
     	iifname "{{.hostName}}" ip6 nexthdr ipv6-icmp icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert } accept
    +
    +	{{ if .dnsIPv4 }}
    +	{{ range .dnsIPv4 }}
    +	iifname "{{$.hostName}}" ip daddr "{{.}}" tcp dport 53 accept
    +	iifname "{{$.hostName}}" ip daddr "{{.}}" udp dport 53 accept
    +	{{ end }}
    +	{{ end }}
    +
    +	{{ if .dnsIPv6 }}
    +	{{ range .dnsIPv6 }}
    +	iifname "{{$.hostName}}" ip6 daddr "{{.}}" tcp dport 53 accept
    +	iifname "{{$.hostName}}" ip6 daddr "{{.}}" udp dport 53 accept
    +	{{ end }}
    +	{{ end }}
    +
     	{{ end }}
     
     	# ACLs
    
a7c33301738a

incusd/firewall: Add basic rules on nftables

https://github.com/lxc/incusStéphane GraberApr 13, 2025via ghsa
5 files changed · +70 6
  • internal/server/device/nic_bridged.go+41 3 modified
    @@ -1182,11 +1182,50 @@ func (d *nicBridged) setFilters() (err error) {
     	defer revert.Fail()
     	revert.Add(func() { d.removeFilters(config) })
     
    -	IPv4Nets, IPv6Nets, err := allowedIPNets(config)
    +	ipv4Nets, ipv6Nets, err := allowedIPNets(config)
     	if err != nil {
     		return err
     	}
     
    +	var ipv4DNS []string
    +	var ipv6DNS []string
    +
    +	if d.network != nil {
    +		netConfig := d.network.Config()
    +
    +		ipv4DNS = []string{}
    +		ipv6DNS = []string{}
    +
    +		// Pull directly configured DNS name servers (if any).
    +		nsList := util.SplitNTrimSpace(netConfig["dns.nameservers"], ",", -1, false)
    +		for _, ns := range nsList {
    +			if ns == "" {
    +				continue
    +			}
    +
    +			nsIP := net.ParseIP(ns)
    +			if nsIP == nil {
    +				return fmt.Errorf("Invalid DNS nameserver")
    +			}
    +
    +			if nsIP.To4() == nil {
    +				ipv4DNS = append(ipv4DNS, ns)
    +			} else {
    +				ipv6DNS = append(ipv6DNS, ns)
    +			}
    +		}
    +
    +		// Add IPv4 router.
    +		if netConfig["ipv4.address"] != "" && netConfig["ipv4.address"] != "none" {
    +			ipv4DNS = append(ipv4DNS, strings.Split(netConfig["ipv4.address"], "/")[0])
    +		}
    +
    +		// Add IPv6 router.
    +		if netConfig["ipv6.address"] != "" && netConfig["ipv6.address"] != "none" {
    +			ipv6DNS = append(ipv6DNS, strings.Split(netConfig["ipv6.address"], "/")[0])
    +		}
    +	}
    +
     	var aclRules []firewallDrivers.ACLRule
     	var aclNames []string
     	if config["security.acls"] != "" {
    @@ -1202,10 +1241,9 @@ func (d *nicBridged) setFilters() (err error) {
     		if err != nil {
     			return err
     		}
    -
     	}
     
    -	err = d.state.Firewall.InstanceSetupBridgeFilter(d.inst.Project().Name, d.inst.Name(), d.name, d.config["parent"], d.config["host_name"], d.config["hwaddr"], IPv4Nets, IPv6Nets, d.network != nil, util.IsTrue(config["security.mac_filtering"]), aclRules)
    +	err = d.state.Firewall.InstanceSetupBridgeFilter(d.inst.Project().Name, d.inst.Name(), d.name, d.config["parent"], d.config["host_name"], d.config["hwaddr"], ipv4Nets, ipv6Nets, ipv4DNS, ipv6DNS, d.network != nil, util.IsTrue(config["security.mac_filtering"]), aclRules)
     	if err != nil {
     		return err
     	}
    
  • internal/server/firewall/drivers/drivers_nftables.go+5 1 modified
    @@ -401,7 +401,7 @@ func (d Nftables) instanceDeviceLabel(projectName, instanceName, deviceName stri
     }
     
     // InstanceSetupBridgeFilter sets up the filter rules to apply bridged device IP filtering.
    -func (d Nftables) InstanceSetupBridgeFilter(projectName string, instanceName string, deviceName string, parentName string, hostName string, hwAddr string, IPv4Nets []*net.IPNet, IPv6Nets []*net.IPNet, parentManaged bool, macFiltering bool, aclRules []ACLRule) error {
    +func (d Nftables) InstanceSetupBridgeFilter(projectName string, instanceName string, deviceName string, parentName string, hostName string, hwAddr string, IPv4Nets []*net.IPNet, IPv6Nets []*net.IPNet, IPv4DNS []string, IPv6DNS []string, parentManaged bool, macFiltering bool, aclRules []ACLRule) error {
     	deviceLabel := d.instanceDeviceLabel(projectName, instanceName, deviceName)
     
     	mac, err := net.ParseMAC(hwAddr)
    @@ -480,6 +480,10 @@ func (d Nftables) InstanceSetupBridgeFilter(projectName string, instanceName str
     	tplFields["aclOutAcceptRules"] = nftRules.outAcceptRules
     	tplFields["aclOutDefaultRule"] = nftRules.defaultOutRule
     
    +	// Required for basic connectivity
    +	tplFields["dnsIPv4"] = IPv4DNS
    +	tplFields["dnsIPv6"] = IPv6DNS
    +
     	err = d.applyNftConfig(nftablesInstanceBridgeFilter, tplFields)
     	if err != nil {
     		return fmt.Errorf("Failed adding bridge filter rules for instance device %q (%s): %w", deviceLabel, tplFields["family"], err)
    
  • internal/server/firewall/drivers/drivers_nftables_templates.go+22 0 modified
    @@ -190,6 +190,24 @@ chain in{{.chainSeparator}}{{.deviceLabel}} {
     	{{ if or .aclInDropRules .aclInRejectRules .aclInAcceptRules .aclOutDropRules .aclOutAcceptRules .aclInDefaultRule }}
     	ct state established,related accept
     
    +	{{ if .dnsIPv4 }}
    +	{{ range .dnsIPv4 }}
    +	iifname "{{$.hostName}}" ip daddr "{{.}}" tcp dport 53 accept
    +	iifname "{{$.hostName}}" ip daddr "{{.}}" udp dport 53 accept
    +	{{ end }}
    +	{{ end }}
    +
    +	{{ if .dnsIPv6 }}
    +	{{ range .dnsIPv6 }}
    +	iifname "{{$.hostName}}" ip6 daddr "{{.}}" tcp dport 53 accept
    +	iifname "{{$.hostName}}" ip6 daddr "{{.}}" udp dport 53 accept
    +	{{ end }}
    +	{{ end }}
    +
    +	iifname "{{.hostName}}" ether type ip ip saddr 0.0.0.0 ip daddr 255.255.255.255 udp dport 67 accept
    +	iifname "{{.hostName}}" ether type ip6 ip6 saddr fe80::/10 ip6 daddr ff02::1:2 udp dport 547 accept
    +	iifname "{{.hostName}}" ether type ip6 ip6 saddr fe80::/10 ip6 daddr ff02::2 icmpv6 type 133 accept
    +
     	iifname "{{.hostName}}" ether type arp accept
     	iifname "{{.hostName}}" ip6 nexthdr ipv6-icmp icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert } accept
     	{{ end }}
    @@ -323,6 +341,10 @@ chain out{{.chainSeparator}}{{.deviceLabel}} {
     	oifname "{{.hostName}}" ether type arp accept
     	oifname "{{.hostName}}" ip6 nexthdr ipv6-icmp icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert } accept
     
    +	oifname "{{.hostName}}" udp sport 67 udp dport 68 accept
    +	oifname "{{.hostName}}" ip6 saddr fe80::/10 udp sport 547 accept
    +	oifname "{{.hostName}}" ip6 saddr fe80::/10 icmpv6 type {1, 2, 3, 4, 128, 134, 135, 136, 143} accept
    +
     	# Network ACLs
     	{{ range .aclOutDropRules}}
     	{{.}}
    
  • internal/server/firewall/drivers/drivers_xtables.go+1 1 modified
    @@ -811,7 +811,7 @@ func (d Xtables) instanceDeviceIPTablesComment(projectName string, instanceName
     // If the parent bridge is managed by Incus then parentManaged argument should be true so that the rules added can
     // use the iptablesChainACLFilterPrefix chain. If not they are added to the main filter chains directly (which only
     // works for unmanaged bridges because those don't support ACLs).
    -func (d Xtables) InstanceSetupBridgeFilter(projectName string, instanceName string, deviceName string, parentName string, hostName string, hwAddr string, IPv4Nets []*net.IPNet, IPv6Nets []*net.IPNet, parentManaged bool, macFiltering bool, aclRules []ACLRule) error {
    +func (d Xtables) InstanceSetupBridgeFilter(projectName string, instanceName string, deviceName string, parentName string, hostName string, hwAddr string, IPv4Nets []*net.IPNet, IPv6Nets []*net.IPNet, IPv4DNS []string, IPv6DNS []string, parentManaged bool, macFiltering bool, aclRules []ACLRule) error {
     	if len(aclRules) > 0 {
     		return fmt.Errorf("ACL rules not supported for xtables bridge filtering")
     	}
    
  • internal/server/firewall/firewall_interface.go+1 1 modified
    @@ -27,7 +27,7 @@ type Firewall interface {
     	NetworkApplyAddressSets(sets []drivers.AddressSet, nftTable string) error
     	NetworkDeleteAddressSetsIfUnused(nftTable string) error
     
    -	InstanceSetupBridgeFilter(projectName string, instanceName string, deviceName string, parentName string, hostName string, hwAddr string, IPv4Nets []*net.IPNet, IPv6Nets []*net.IPNet, parentManaged bool, macFiltering bool, aclRules []drivers.ACLRule) error
    +	InstanceSetupBridgeFilter(projectName string, instanceName string, deviceName string, parentName string, hostName string, hwAddr string, IPv4Nets []*net.IPNet, IPv6Nets []*net.IPNet, IPv4DNS []string, IPv6DNS []string, parentManaged bool, macFiltering bool, aclRules []drivers.ACLRule) error
     	InstanceClearBridgeFilter(projectName string, instanceName string, deviceName string, parentName string, hostName string, hwAddr string, IPv4Nets []*net.IPNet, IPv6Nets []*net.IPNet) error
     
     	InstanceSetupProxyNAT(projectName string, instanceName string, deviceName string, forward *drivers.AddressForward) error
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.