CVE-2018-14635
Description
When using the Linux bridge ml2 driver, non-privileged tenants are able to create and attach ports without specifying an IP address, bypassing IP address validation. A potential denial of service could occur if an IP address, conflicting with existing guests or routers, is then assigned from outside of the allowed allocation pool. Versions of openstack-neutron before 13.0.0.0b2, 12.0.3 and 11.0.5 are vulnerable.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Non-privileged tenants can bypass IP address validation in OpenStack Neutron's Linux bridge driver, leading to potential denial of service via IP conflicts.
Vulnerability
The vulnerability resides in the Linux bridge ml2 driver of OpenStack Neutron. Non-privileged tenants are able to create and attach ports without specifying an IP address, bypassing IP address validation. This allows an IP address to be assigned from outside the allowed allocation pool, potentially conflicting with existing guests or routers. Affected versions are openstack-neutron before 13.0.0.0b2, 12.0.3, and 11.0.5. [1]
Exploitation
An attacker must be a non-privileged tenant with network access to create and attach ports. The attacker can create a port without specifying an IP address, then later an IP address from outside the subnet's allocation pool can be assigned (e.g., via DHCP or manual assignment). This can cause IP conflicts with existing guests or routers. No authentication bypass beyond tenant privileges is required. [1]
Impact
Successful exploitation leads to a denial of service (DoS) condition. The IP conflict can disrupt network connectivity for existing guests or routers, potentially causing service unavailability. The impact is limited to network layer disruption; no data confidentiality or integrity compromise is reported. [1][2]
Mitigation
Red Hat released updates: RHSA-2018:2710 for OpenStack 13 (Queens) with openstack-neutron-12.0.3-5.el7ost, RHSA-2018:3792 for OpenStack 12 (Pike) with openstack-neutron-11.0.4-6.el7ost, and RHSA-2018:2715 for OpenStack 10 (Newton) with openstack-neutron-10.0.5-5.el7ost. [2][3][4] Upstream fixed versions are 13.0.0.0b2, 12.0.3, and 11.0.5. [1] No workaround is documented; upgrading to the fixed version is recommended.
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
neutronPyPI | >= 13.0.0.0b1, < 13.0.0.0b2 | 13.0.0.0b2 |
neutronPyPI | < 11.0.6 | 11.0.6 |
neutronPyPI | >= 12.0.0, < 12.0.4 | 12.0.4 |
Affected products
2- The Openstack Project/openstack-neutronv5Range: 13.0.0.0b2, 12.0.3, 11.0.5
Patches
154aa6e81cb17Disallow router interface out of subnet IP range
2 files changed · +82 −0
neutron/db/l3_db.py+26 −0 modified@@ -692,6 +692,27 @@ def _check_router_port(self, context, port_id, device_id): raise n_exc.BadRequest(resource='router', msg=msg) return port + def _validate_port_in_range_or_admin(self, context, subnets, port): + if context.is_admin: + return + subnets_by_id = {} + for s in subnets: + addr_set = netaddr.IPSet() + for range in s['allocation_pools']: + addr_set.add(netaddr.IPRange(netaddr.IPAddress(range['start']), + netaddr.IPAddress(range['end']))) + subnets_by_id[s['id']] = (addr_set, s['project_id'],) + for subnet_id, ip in [(fix_ip['subnet_id'], fix_ip['ip_address'],) + for fix_ip in port['fixed_ips']]: + if (ip not in subnets_by_id[subnet_id][0] and + context.project_id != subnets_by_id[subnet_id][1]): + msg = (_('Cannot add interface to router because specified ' + 'port %(port)s has an IP address out of the ' + 'allocation pool of subnet %(subnet)s, which is not ' + 'owned by the project making the request') % + {'port': port['id'], 'subnet': subnet_id}) + raise n_exc.BadRequest(resource='router', msg=msg) + def _validate_router_port_info(self, context, router, port_id): with db_api.autonested_transaction(context.session): # check again within transaction to mitigate race @@ -727,6 +748,7 @@ def _validate_router_port_info(self, context, router, port_id): msg = _("Cannot have multiple " "IPv4 subnets on router port") raise n_exc.BadRequest(resource='router', msg=msg) + self._validate_port_in_range_or_admin(context, subnets, port) return port, subnets def _notify_attaching_interface(self, context, router_db, port, @@ -788,6 +810,10 @@ def _add_interface_by_subnet(self, context, router, subnet_id, owner): if not subnet['gateway_ip']: msg = _('Subnet for router interface must have a gateway IP') raise n_exc.BadRequest(resource='router', msg=msg) + if subnet['project_id'] != context.project_id and not context.is_admin: + msg = (_('Cannot add interface to router because subnet %s is not ' + 'owned by project making the request') % subnet_id) + raise n_exc.BadRequest(resource='router', msg=msg) if (subnet['ip_version'] == 6 and subnet['ipv6_ra_mode'] is None and subnet['ipv6_address_mode'] is not None): msg = (_('IPv6 subnet %s configured to receive RAs from an '
neutron/tests/unit/extensions/test_l3.py+56 −0 modified@@ -1265,6 +1265,62 @@ def test_router_add_interface_subnet_with_bad_tenant_returns_404(self): expected_code=err_code, tenant_id='bad_tenant') + def test_router_add_interface_by_subnet_other_tenant_subnet_returns_400( + self): + router_tenant_id = _uuid() + with self.router(tenant_id=router_tenant_id, set_context=True) as r: + with self.network(shared=True) as n: + with self.subnet(network=n) as s: + err_code = exc.HTTPBadRequest.code + self._router_interface_action('add', + r['router']['id'], + s['subnet']['id'], + None, + expected_code=err_code, + tenant_id=router_tenant_id) + + def _test_router_add_interface_by_port_allocation_pool( + self, out_of_pool=False, router_action_as_admin=False, + expected_code=exc.HTTPOk.code): + router_tenant_id = _uuid() + with self.router(tenant_id=router_tenant_id, set_context=True) as r: + with self.network(shared=True) as n: + with self.subnet(network=n) as s1, ( + self.subnet(network=n, cidr='fd00::/64', + ip_version=6)) as s2, ( + self.subnet(network=n, cidr='fd01::/64', + ip_version=6)) as s3: + fixed_ips = [{'subnet_id': s1['subnet']['id']}, + {'subnet_id': s2['subnet']['id']}, + {'subnet_id': s3['subnet']['id']}] + if out_of_pool: + fixed_ips[1] = {'subnet_id': s2['subnet']['id'], + 'ip_address': + s2['subnet']['gateway_ip']} + with self.port(subnet=s1, fixed_ips=fixed_ips, + tenant_id=router_tenant_id, + set_context=True) as p: + kwargs = {'expected_code': expected_code} + if not router_action_as_admin: + kwargs['tenant_id'] = router_tenant_id + self._router_interface_action( + 'add', r['router']['id'], None, p['port']['id'], + **kwargs) + + def test_router_add_interface_by_port_other_tenant_address_in_pool( + self): + self._test_router_add_interface_by_port_allocation_pool() + + def test_router_add_interface_by_port_other_tenant_address_out_of_pool( + self): + self._test_router_add_interface_by_port_allocation_pool( + out_of_pool=True, expected_code=exc.HTTPBadRequest.code) + + def test_router_add_interface_by_port_admin_address_out_of_pool( + self): + self._test_router_add_interface_by_port_allocation_pool( + out_of_pool=True, router_action_as_admin=True) + def test_router_add_interface_subnet_with_port_from_other_tenant(self): tenant_id = _uuid() other_tenant_id = _uuid()
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
11- access.redhat.com/errata/RHSA-2018:2710ghsavendor-advisoryx_refsource_REDHATWEB
- access.redhat.com/errata/RHSA-2018:2715ghsavendor-advisoryx_refsource_REDHATWEB
- access.redhat.com/errata/RHSA-2018:2721ghsavendor-advisoryx_refsource_REDHATWEB
- access.redhat.com/errata/RHSA-2018:3792ghsavendor-advisoryx_refsource_REDHATWEB
- github.com/advisories/GHSA-x634-34m9-96mpghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2018-14635ghsaADVISORY
- bugs.launchpad.net/neutron/+bug/1757482ghsax_refsource_CONFIRMWEB
- bugzilla.redhat.com/show_bug.cgighsax_refsource_CONFIRMWEB
- git.openstack.org/cgit/openstack/neutron/commit/ghsax_refsource_CONFIRMWEB
- github.com/openstack/neutron/commit/54aa6e81cb17b33ce4d5d469cc11dec2869c762dghsaWEB
- github.com/pypa/advisory-database/tree/main/vulns/neutron/PYSEC-2018-93.yamlghsaWEB
News mentions
0No linked articles in our index yet.