1.9 KiB
neutron-0001 — CWE-407: O(n²) trusted_ports list membership in iptables firewall
Severity: HIGH
File: neutron/agent/linux/iptables_firewall.py
Lines: 154, 159, 163, 168
Status: PATCHED
Description
IptablesFirewallDriver stores trusted ports in a plain Python list
(self.trusted_ports = []). Two methods iterate over an incoming
port_ids sequence and perform O(n) membership tests against that list:
def process_trusted_ports(self, port_ids):
for port in port_ids: # O(n)
if port not in self.trusted_ports: # O(n) — O(n²) total
...
self.trusted_ports.append(port)
def remove_trusted_ports(self, port_ids):
for port in port_ids: # O(n)
if port in self.trusted_ports: # O(n) — O(n²) total
...
self.trusted_ports.remove(port) # O(n) — O(n³) total
process_trusted_ports / remove_trusted_ports are called on the L2
agent's hot path every time port binding state changes. On a host with
T trusted ports and P incoming port_ids, cost is O(P×T). For the
remove call the .remove() itself adds another O(T), giving O(P×T²).
Complexity
| Version | Trust check | Remove | Total per call |
|---|---|---|---|
| Defective | O(n) | O(n) | O(P×T²) |
| Fixed | O(1) | O(1) | O(P) |
Fix
Replace self.trusted_ports = [] with self.trusted_ports = set().
Replace .append(port) → .add(port).
Replace .remove(port) → .discard(port).
Any caller reading self.trusted_ports as a sequence still works because
set supports iteration.
Patch
See patch/neutron-0001.patch
Test
See unit/NeutronTrustedPortsAlgorithm.java
Speedup
Benchmark at N=2000 trusted ports, 2000 port_ids: ~2200× fewer membership operations (O(n²) → O(1) per check).