CVE-2021-47391 RDMA/cma: Ensure rdma_addr_cancel() happens before issuing more requests

High 7.8 Published Updated

A race condition in the Linux kernel RDMA subsystem allows a use-after-free, potentially leading to code execution or privilege escalation.

Exploited in the wild
Not known
Login needed
Any signed-in user
Attackable
Local or same network only
Victim action needed
Not needed
Fix
Available

What is CVE-2021-47391?

CVE-2021-47391 is a high-severity use after free vulnerability in Linux kernel, published on 21 May 2024. It can only be exploited from the same machine or local network, with no action from the victim.

Official description

In the Linux kernel, the following vulnerability has been resolved:

RDMA/cma: Ensure rdma_addr_cancel() happens before issuing more requests

The FSM can run in a circle allowing rdma_resolve_ip() to be called twice on the same id_priv. While this cannot happen without going through the work, it violates the invariant that the same address resolution background request cannot be active twice.

CPU 1 CPU 2

rdma_resolve_addr(): RDMA_CM_IDLE -> RDMA_CM_ADDR_QUERY rdma_resolve_ip(addr_handler) #1

process_one_req(): for #1 addr_handler(): RDMA_CM_ADDR_QUERY -> RDMA_CM_ADDR_BOUND mutex_unlock(&id_priv->handler_mutex); [.. handler still running ..]

rdma_resolve_addr(): RDMA_CM_ADDR_BOUND -> RDMA_CM_ADDR_QUERY rdma_resolve_ip(addr_handler) !! two requests are now on the req_list

rdma_destroy_id(): destroy_id_handler_unlock(): _destroy_id(): cma_cancel_operation(): rdma_addr_cancel()

// process_one_req() self removes it spin_lock_bh(&lock); cancel_delayed_work(&req->work); if (!list_empty(&req->list)) == true

! rdma_addr_cancel() returns after process_on_req #1 is done

kfree(id_priv)

process_one_req(): for #2 addr_handler(): mutex_lock(&id_priv->handler_mutex); !! Use after free on id_priv

rdma_addr_cancel() expects there to be one req on the list and only cancels the first one. The self-removal behavior of the work only happens after the handler has returned. This yields a situations where the req_list can have two reqs for the same "handle" but rdma_addr_cancel() only cancels the first one.

The second req remains active beyond rdma_destroy_id() and will use-after-free id_priv once it inevitably triggers.

Fix this by remembering if the id_priv has called rdma_resolve_ip() and always cancel before calling it again. This ensures the req_list never gets more than one item in it and doesn't cost anything in the normal flow that never uses this strange error path.

Weakness: CWE-416

Which versions are affected by CVE-2021-47391?

It affects 1 product.

Products include Linux kernel.

How do I fix CVE-2021-47391?

Apply the vendor's patch.

Upgrade to the fixed version. These bugs are found with fuzzing and sanitisers and avoided by memory-safe languages. More about Use after free.

Is CVE-2021-47391 being exploited?

There is no known exploitation of CVE-2021-47391 in the wild and no public exploit code.

All Linux kernel vulnerabilities

Sources

Also known as DEBIAN-CVE-2021-47391, GHSA-xwrf-hhx9-vmhv, UBUNTU-CVE-2021-47391.

Is CVE-2021-47391 in your software?

Upload an SBOM and sbomify checks it against every vulnerability here, every day.

Check your SBOMs for free