Floating IP attach/detach fails for non-admin user and unbound port with router in different tenant

Bug #1802006 reported by Arjun Baindur
18
This bug affects 3 people
Affects Status Importance Assigned to Milestone
neutron
Fix Released
Medium
Brian Haley

Bug Description

Seeing this on pike, but code looks same in master so issue still likely exists.

We have a shared external network connected to router in TenantA. Now create a network, either shared in tenantA or owned by tenantB, and attach to tenantA's router (an admin user will have to do this).

Now suppose a non-admin user in the different tenantB creates a Floating IP on shared ext network. They then try to attach it to a port. It passes if the port is bound to a VM. It fails if the port is unbound. For example, pre-create a port on a network/subnet available to this tenant, and then try the following /floatingips/ PUT API call. It will fail. Then bring up a VM on same network, and attach Floating IP to it's port, this will pass:

curl -k -X PUT -i https://localhost/neutron/v2.0/floatingips/cc56cbb4-2c3b-4d53-9506-1baaa8e7b2d6 -H "X-Auth-Token: $TOK" -H "Content-Type: application/json" -d '{"floatingip": {"port_id": "6af4bb1c-85b4-42c0-8b96-6efb90443aa7"}}'
HTTP/1.1 404 Not Found
Server: nginx/1.12.2
Date: Tue, 06 Nov 2018 07:31:54 GMT
Content-Type: application/json
Content-Length: 135
Connection: keep-alive
X-Openstack-Request-Id: req-31b02819-844c-4d41-a471-938f092b4a57
Access-Control-Allow-Credentials: true

{"NeutronError": {"message": "Router b819cfbb-7e8b-4bce-964e-ec4b29614241 could not be found", "type": "RouterNotFound", "detail": ""}}

curl -k -X PUT -i https://localhost/neutron/v2.0/floatingips/44361b51-7928-441e-8478-4fd35919e5c3 -H "X-Auth-Token: $TOK" -H "Content-Type: application/json" -d '{"floatingip": {"port_id": "7ea1b40a-e3b1-490d-8a02-d5e2cf18b89c"}}'
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Tue, 06 Nov 2018 07:15:10 GMT
Content-Type: application/json
Content-Length: 584
Connection: keep-alive
X-Openstack-Request-Id: req-50cb5289-fcbb-4a65-91d4-33f59b0f4632
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: X-Subject-Token

{"floatingip": {"router_id": "b819cfbb-7e8b-4bce-964e-ec4b29614241", "status": "DOWN", "description": "", "tags": [], "updated_at": "2018-11-06T07:15:09Z", "dns_domain": "", "floating_network_id": "6580471a-cac0-4f03-ae2e-77ddfb76b181", "fixed_ip_address": "10.168.1.14", "floating_ip_address": "10.4.252.154", "revision_number": 16, "port_id": "7ea1b40a-e3b1-490d-8a02-d5e2cf18b89c", "id": "44361b51-7928-441e-8478-4fd35919e5c3", "dns_name": "", "created_at": "2018-11-06T02:53:23Z", "tenant_id": "5e09d64a521b440e9ffbec28f5fb7de0", "project_id": "5e09d64a521b440e9ffbec28f5fb7de0"}}

Problem is due to new code which allows binding FIP to unbound ports via SNAT router, from this diff: https://github.com/openstack/neutron/commit/9515c771e742a5b6d29b17f84f49a0b39706489b

An additional get_router() call is made here, and it needs the elevated admin context to be passed in. It fails because default policy for get_router is admin_or_owner, and it can't fetch the SNAT router in different tenant. This code path is not hit for a VM port, as it is bound and has a host:

https://github.com/openstack/neutron/blob/master/neutron/db/l3_dvr_db.py#L1098

which invokes get_router() here:

https://github.com/openstack/neutron/blob/master/neutron/db/l3_hascheduler_db.py#L45

Need to pass in context.elevated() in either one of those 2 places - thinking the first location might be better?

Revision history for this message
Arjun Baindur (abaindur) wrote :

 I have verified that changing "context" to "context.elevated()" at https://github.com/openstack/neutron/blob/master/neutron/db/l3_dvr_db.py#L1098 fixes the issue, at least for the API example I gave above

description: updated
Revision history for this message
Brian Haley (brian-haley) wrote :

Hi Arjun,

Yes, that change looks correct, and mimics code earlier in that method that looks up the router:

https://github.com/openstack/neutron/blob/master/neutron/db/l3_dvr_db.py#L1065

Changed in neutron:
status: New → Confirmed
importance: Undecided → Medium
Revision history for this message
Arjun Baindur (abaindur) wrote :

Cool thanks. I will fix it and try to send review out by this week, assuming unit tests pass

Changed in neutron:
assignee: nobody → Arjun Baindur (abaindur)
Revision history for this message
Swaminathan Vasudevan (swaminathan-vasudevan) wrote :

Looks ok to me. Go ahead and push a patch if you already have one.

tags: added: l3-dvr-backlog
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to neutron (master)

Fix proposed to branch: master
Review: https://review.openstack.org/622623

Changed in neutron:
status: Confirmed → In Progress
Changed in neutron:
assignee: Arjun Baindur (abaindur) → Brian Haley (brian-haley)
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to neutron (master)

Reviewed: https://review.openstack.org/622623
Committed: https://git.openstack.org/cgit/openstack/neutron/commit/?id=a02f8a95f752903e7520af286acbaab61a031ece
Submitter: Zuul
Branch: master

commit a02f8a95f752903e7520af286acbaab61a031ece
Author: Arjun Baindur <email address hidden>
Date: Tue Dec 4 15:48:51 2018 -0800

    Pass elevated admin context when fetching snat router for FIP to unbound port

    If a floating IP is assigned to an unbound port, it is scheduled to the SNAT router.
    This fails when the router is in a different tenant and user is not an admin.
    This was previously working, but broken with the changes for enabling
    centralized FIP/unbound port.

    A common usecase for this when not using a true VIP is a port and Floating IP may be
    precreated as a pair, and then attached to a VM.
    It works otherwise if the port is already bound to a VM.

    Change-Id: I0ee5344216fdff0a9e3bd6fa165f8d0aa736ac85
    Closes-Bug: #1802006

Changed in neutron:
status: In Progress → Fix Released
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix included in openstack/neutron 14.0.0.0b2

This issue was fixed in the openstack/neutron 14.0.0.0b2 development milestone.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.