VYPR
Unrated severityNVD Advisory· Published May 28, 2026

CVE-2026-46189

CVE-2026-46189

Description

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

RDMA/vmw_pvrdma: Fix double free on pvrdma_alloc_ucontext() error path

Sashiko points out that pvrdma_uar_free() is already called within pvrdma_dealloc_ucontext(), so calling it before triggers a double free.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Double-free vulnerability in VMware's pvrdma driver error path leads to potential memory corruption.

Vulnerability

In the Linux kernel's RDMA/vmw_pvrdma driver, the pvrdma_alloc_ucontext() function contains a double-free bug on its error path. Specifically, pvrdma_uar_free() is called before invoking pvrdma_dealloc_ucontext(), which itself already calls pvrdma_uar_free(), resulting in a double-free of the UAR (user access region) object. This affects kernel versions prior to the commit that fixes it [1].

Exploitation

An attacker must have the ability to trigger the error path in pvrdma_alloc_ucontext(), which likely requires local access to a VMware VM with the pvrdma device enabled and the ability to cause allocation failures (e.g., through resource exhaustion). No authentication beyond local user access is needed.

Impact

Successful exploitation results in a double-free, which can lead to memory corruption, potentially enabling privilege escalation or denial of service. The exact impact depends on kernel memory allocator behavior and mitigations like slab freelist randomization.

Mitigation

Apply the kernel commit ecc36a82ecfcfdf3c6606d209f22ec5543c410e0 [1] which moves the pvrdma_uar_free() call to avoid the double-free. Users should update to a kernel version containing this fix. No workarounds are available.

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

1

Patches

10
e38e86995df2

RDMA/vmw_pvrdma: Fix double free on pvrdma_alloc_ucontext() error path

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitJason GunthorpeApr 28, 2026Fixed in 7.1-rc3via kernel-cna
2 files changed · +2 4
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index bcd43dc30e21c6..c7c2b41060e526 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -322,7 +322,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index bcd43dc30e21c6..c7c2b41060e526 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -322,7 +322,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
45d25e3ec179

RDMA/vmw_pvrdma: Fix double free on pvrdma_alloc_ucontext() error path

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitJason GunthorpeApr 28, 2026Fixed in 6.12.88via kernel-cna
2 files changed · +2 4
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index 9f54aa90a35a67..dde1910dd8b132 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -350,7 +350,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index 9f54aa90a35a67..dde1910dd8b132 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -350,7 +350,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
935ee27d0904

RDMA/vmw_pvrdma: Fix double free on pvrdma_alloc_ucontext() error path

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitJason GunthorpeApr 28, 2026Fixed in 7.0.7via kernel-cna
2 files changed · +2 4
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index bcd43dc30e21c6..c7c2b41060e526 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -322,7 +322,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index bcd43dc30e21c6..c7c2b41060e526 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -322,7 +322,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
0c63333ff97b

RDMA/vmw_pvrdma: Fix double free on pvrdma_alloc_ucontext() error path

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitJason GunthorpeApr 28, 2026Fixed in 6.18.30via kernel-cna
2 files changed · +2 4
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index bcd43dc30e21c6..c7c2b41060e526 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -322,7 +322,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index bcd43dc30e21c6..c7c2b41060e526 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -322,7 +322,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
ecc36a82ecfc

RDMA/vmw_pvrdma: Fix double free on pvrdma_alloc_ucontext() error path

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitJason GunthorpeApr 28, 2026Fixed in 6.6.140via kernel-cna
2 files changed · +2 4
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index 9f54aa90a35a67..dde1910dd8b132 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -350,7 +350,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index 9f54aa90a35a67..dde1910dd8b132 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -350,7 +350,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
ecc36a82ecfc

RDMA/vmw_pvrdma: Fix double free on pvrdma_alloc_ucontext() error path

2 files changed · +2 4
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index 9f54aa90a35a67..dde1910dd8b132 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -350,7 +350,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index 9f54aa90a35a67..dde1910dd8b132 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -350,7 +350,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
45d25e3ec179

RDMA/vmw_pvrdma: Fix double free on pvrdma_alloc_ucontext() error path

2 files changed · +2 4
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index 9f54aa90a35a67..dde1910dd8b132 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -350,7 +350,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index 9f54aa90a35a67..dde1910dd8b132 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -350,7 +350,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
e38e86995df2

RDMA/vmw_pvrdma: Fix double free on pvrdma_alloc_ucontext() error path

2 files changed · +2 4
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index bcd43dc30e21c6..c7c2b41060e526 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -322,7 +322,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index bcd43dc30e21c6..c7c2b41060e526 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -322,7 +322,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
0c63333ff97b

RDMA/vmw_pvrdma: Fix double free on pvrdma_alloc_ucontext() error path

2 files changed · +2 4
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index bcd43dc30e21c6..c7c2b41060e526 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -322,7 +322,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index bcd43dc30e21c6..c7c2b41060e526 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -322,7 +322,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
935ee27d0904

RDMA/vmw_pvrdma: Fix double free on pvrdma_alloc_ucontext() error path

2 files changed · +2 4
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index bcd43dc30e21c6..c7c2b41060e526 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -322,7 +322,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c+1 2 modified
    diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    index bcd43dc30e21c6..c7c2b41060e526 100644
    --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
    @@ -322,7 +322,7 @@ int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
     	uresp.qp_tab_size = vdev->dsr->caps.max_qp;
     	ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
     	if (ret) {
    -		pvrdma_uar_free(vdev, &context->uar);
    +		/* pvrdma_dealloc_ucontext() also frees the UAR */
     		pvrdma_dealloc_ucontext(&context->ibucontext);
     		return -EFAULT;
     	}
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Redundant call to pvrdma_uar_free() before pvrdma_dealloc_ucontext(), which itself frees the UAR, causing a double-free."

Attack vector

An attacker who can trigger a failure of `ib_copy_to_udata()` (e.g., by causing a copy-to-userspace fault) during `pvrdma_alloc_ucontext()` will hit the error path. That path first calls `pvrdma_uar_free()` and then `pvrdma_dealloc_ucontext()`, which itself calls `pvrdma_uar_free()` again, resulting in a double-free of the UAR (User Access Region) resource. No special network path or authentication is required beyond the ability to invoke the RDMA ucontext allocation ioctl.

Affected code

The bug is in `drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c` in the function `pvrdma_alloc_ucontext()` [patch_id=2897920]. The error path at line 322 (or 350 depending on backport) called `pvrdma_uar_free()` followed by `pvrdma_dealloc_ucontext()`, but the latter already calls `pvrdma_uar_free()` internally.

What the fix does

The patch removes the explicit `pvrdma_uar_free()` call from the error path, leaving only `pvrdma_dealloc_ucontext()` [patch_id=2897920]. As the added comment explains, "pvrdma_dealloc_ucontext() also frees the UAR", so the standalone `pvrdma_uar_free()` was redundant and caused a double-free. The fix ensures the UAR is freed exactly once.

Preconditions

  • inputThe attacker must be able to invoke the RDMA ucontext allocation path (pvrdma_alloc_ucontext) on a system with the vmw_pvrdma driver loaded.
  • inputThe ib_copy_to_udata() call must fail, e.g., due to a fault when copying to userspace.

Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.