diff --git a/neutron/db/securitygroups_db.py b/neutron/db/securitygroups_db.py index b08b5bd78c8..58e573f64db 100644 --- a/neutron/db/securitygroups_db.py +++ b/neutron/db/securitygroups_db.py @@ -928,6 +928,10 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase, :returns: the default security group id for given tenant. """ + # Do not allow a tenant to create a default SG for another one. + # See Bug 1987410. + if tenant_id != context.tenant_id and not context.is_admin: + return if not extensions.is_extension_supported(self, 'security-group'): return default_group_id = self._get_default_sg_id(context, tenant_id) diff --git a/neutron/tests/unit/db/test_securitygroups_db.py b/neutron/tests/unit/db/test_securitygroups_db.py index 7e978c6f9cf..593272027b7 100644 --- a/neutron/tests/unit/db/test_securitygroups_db.py +++ b/neutron/tests/unit/db/test_securitygroups_db.py @@ -660,3 +660,15 @@ class SecurityGroupDbMixinTestCase(testlib_api.SqlTestCase): self.mixin._ensure_default_security_group(self.ctx, 'tenant_1') create_sg.assert_not_called() get_default_sg_id.assert_not_called() + + def test__ensure_default_security_group_tenant_mismatch(self): + with mock.patch.object( + self.mixin, '_get_default_sg_id') as get_default_sg_id,\ + mock.patch.object( + self.mixin, 'create_security_group') as create_sg: + context = mock.Mock() + context.tenant_id = 'tenant_0' + context.is_admin = False + self.mixin._ensure_default_security_group(context, 'tenant_1') + create_sg.assert_not_called() + get_default_sg_id.assert_not_called()