CVE-2026-46178
Description
In the Linux kernel, the following vulnerability has been resolved:
RDMA/mlx4: Fix resource leak on error in mlx4_ib_create_srq()
Sashiko points out that mlx4_srq_alloc() was not undone during error unwind, add the missing call to mlx4_srq_free().
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Resource leak in Linux kernel RDMA/mlx4 driver when creating SRQ; missing mlx4_srq_free() on error path.
Vulnerability
In the Linux kernel's RDMA/mlx4 driver, the function mlx4_ib_create_srq() fails to call mlx4_srq_free() when an error occurs after a successful mlx4_srq_alloc(). This results in a resource leak. The bug affects kernel versions prior to the fix commit c5dc30da990045105c9762248d23076223e7878a [1].
Exploitation
An attacker with the ability to create an SRQ (typically requiring root or CAP_NET_ADMIN) can trigger the error path by causing a failure after the allocation, for example by exhausting memory or providing invalid parameters. No user interaction beyond initiating the SRQ creation is needed.
Impact
Each failed SRQ creation leaks the allocated resource, leading to gradual memory exhaustion. Over time, this can cause denial of service (DoS) by depleting system memory. No code execution or privilege escalation is possible.
Mitigation
The fix is included in commit c5dc30da990045105c9762248d23076223e7878a [1], which is part of the stable kernel tree. Users should update to a kernel version containing this commit. No workaround is documented.
AI Insight generated on May 28, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
100dbd619716fbRDMA/mlx4: Fix resource leak on error in mlx4_ib_create_srq()
2 files changed · +6 −4
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
e01b8c9286c4RDMA/mlx4: Fix resource leak on error in mlx4_ib_create_srq()
2 files changed · +6 −4
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
c5dc30da9900RDMA/mlx4: Fix resource leak on error in mlx4_ib_create_srq()
2 files changed · +6 −4
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
388617f44d81RDMA/mlx4: Fix resource leak on error in mlx4_ib_create_srq()
2 files changed · +6 −4
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
c54c7e4cb679RDMA/mlx4: Fix resource leak on error in mlx4_ib_create_srq()
2 files changed · +6 −4
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index 5b23e5f8b84aca..767840736d583b 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -194,13 +194,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index 5b23e5f8b84aca..767840736d583b 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -194,13 +194,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
e01b8c9286c4RDMA/mlx4: Fix resource leak on error in mlx4_ib_create_srq()
2 files changed · +6 −4
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
c54c7e4cb679RDMA/mlx4: Fix resource leak on error in mlx4_ib_create_srq()
2 files changed · +6 −4
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index 5b23e5f8b84aca..767840736d583b 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -194,13 +194,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index 5b23e5f8b84aca..767840736d583b 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -194,13 +194,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
c5dc30da9900RDMA/mlx4: Fix resource leak on error in mlx4_ib_create_srq()
2 files changed · +6 −4
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
0dbd619716fbRDMA/mlx4: Fix resource leak on error in mlx4_ib_create_srq()
2 files changed · +6 −4
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
388617f44d81RDMA/mlx4: Fix resource leak on error in mlx4_ib_create_srq()
2 files changed · +6 −4
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
drivers/infiniband/hw/mlx4/srq.c+3 −2 modifieddiff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index c4cf91235eee3a..68e8b04c538808 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -193,13 +193,15 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq, if (udata) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; - goto err_wrid; + goto err_srq; } init_attr->attr.max_wr = srq->msrq.max - 1; return 0; +err_srq: + mlx4_srq_free(dev->dev, &srq->msrq); err_wrid: if (udata) mlx4_ib_db_unmap_user(ucontext, &srq->db); -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing resource deallocation in error path: mlx4_srq_free() was not called when ib_copy_to_udata() fails after a successful mlx4_srq_alloc()."
Attack vector
An attacker with the ability to create an SRQ (Shared Receive Queue) via the RDMA subsystem can trigger the bug by causing `ib_copy_to_udata()` to fail — for example, by providing a user buffer that is too small to hold the SRQ number. When the copy fails, the error path jumps to `err_wrid` and returns `-EFAULT` without freeing the previously allocated SRQ resource [patch_id=2898015]. This leaks kernel memory and SRQ hardware resources, which can be repeated to exhaust system resources.
Affected code
The bug is in `drivers/infiniband/hw/mlx4/srq.c` in the function `mlx4_ib_create_srq()`. The error path after a failed `ib_copy_to_udata()` call jumped to `err_wrid`, which only unmaps the user database but never calls `mlx4_srq_free()` to release the SRQ allocated earlier by `mlx4_srq_alloc()` [patch_id=2898015].
What the fix does
The patch adds a new error label `err_srq` that calls `mlx4_srq_free(dev->dev, &srq->msrq)` before falling through to the existing `err_wrid` cleanup. The `ib_copy_to_udata()` failure now jumps to `err_srq` instead of `err_wrid`, ensuring the SRQ allocated by `mlx4_srq_alloc()` is properly freed on this error path [patch_id=2898015]. This closes the resource leak by making the error unwind symmetric with the allocation order.
Preconditions
- authThe attacker must be able to invoke the RDMA create SRQ operation (requires appropriate RDMA device access or local root privileges on the system).
- inputThe attacker must provide a user buffer (udata) that causes ib_copy_to_udata() to fail, e.g., a buffer too small to hold the SRQ number.
Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/0dbd619716fb07b7de1acd64fec673ee6e1adde7nvd
- git.kernel.org/stable/c/388617f44d81604a760742a0b5de292d411e63e3nvd
- git.kernel.org/stable/c/c54c7e4cb679c0aaa1cb489b9c3f2cd98e63a44cnvd
- git.kernel.org/stable/c/c5dc30da990045105c9762248d23076223e7878anvd
- git.kernel.org/stable/c/e01b8c9286c470b71a38acd320106f2c4f2826a1nvd
News mentions
0No linked articles in our index yet.