VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-46053

CVE-2026-46053

Description

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

net: rds: fix MR cleanup on copy error

__rds_rdma_map() hands sg/pages ownership to the transport after get_mr() succeeds. If copying the generated cookie back to user space fails after that point, the error path must not free those resources again before dropping the MR reference.

Remove the duplicate unpin/free from the put_user() failure branch so that MR teardown is handled only through the existing final cleanup path.

AI Insight

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

A double-free in Linux kernel RDS RDMA on copy_to_user() failure could corrupt memory; fixed by removing redundant cleanup.

Vulnerability

The Linux kernel's __rds_rdma_map() function, introduced in commit b3cb8cae530b, contains a double-free vulnerability. When get_mr() succeeds, ownership of scatter/gather pages is transferred to the transport. If the subsequent put_user() call copying the MR cookie back to userspace fails, the error path incorrectly calls unpin/free on those pages before dropping the MR reference. This leads to a double-free when the final MR cleanup path runs. The vulnerability affects kernel builds with RDS enabled (CONFIG_RDS) and requires local access with AF_RDS socket privileges. [1]

Exploitation

An attacker must have the ability to create an AF_RDS socket and trigger RDMA memory registration via rdma_map on a system exposed to RDS. The exploit requires a race window or a crafted put_user() failure (e.g., by using set_fs() tricks or memory pressure) to cause the cookie copy to fail after a successful get_mr(). The exact sequence involves: calling RDS_GET_MR ioctl, the kernel successfully pins pages and calls transport’s get_mr(), then the kernel fails to copy the MR handle to user space, hitting the erroneous error path that frees pages not owned by the kernel. [1]

Impact

Successful exploitation results in a double-free of kernel memory pages, which can lead to memory corruption, a system crash (denial of service), or potentially arbitrary code execution (kernel compromise) depending on heap layout. The attacker gains no direct data access but can destabilize the system or possibly escalate privileges. The CVE notes no active exploitation in the wild as of the patch date. [1]

Mitigation

The fix is included in Linux kernel stable updates published on 2026-05-27. Patched versions must contain commit b3cb8cae530b2727d8245684148bb49425f6765c. Users should update their kernels to the latest stable release that includes this commit. No workaround is available without patching. The vulnerability is not known to be listed on CISA’s Known Exploited Vulnerabilities catalog. [1]

AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

1

Patches

10
8fdbb6262a4a

net: rds: fix MR cleanup on copy error

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAo ZhouApr 22, 2026Fixed in 6.6.140via kernel-cna
2 files changed · +0 10
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index 00dbcd4d28e680..34d9333e4229f3 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index 00dbcd4d28e680..34d9333e4229f3 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
b3cb8cae530b

net: rds: fix MR cleanup on copy error

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAo ZhouApr 22, 2026Fixed in 7.0.4via kernel-cna
2 files changed · +0 10
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index aa6465dc742c2d..61fb6e45281bf1 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index aa6465dc742c2d..61fb6e45281bf1 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
d95cea9298be

net: rds: fix MR cleanup on copy error

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAo ZhouApr 22, 2026Fixed in 6.12.86via kernel-cna
2 files changed · +0 10
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index 00dbcd4d28e680..34d9333e4229f3 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index 00dbcd4d28e680..34d9333e4229f3 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
033370ffb3c9

net: rds: fix MR cleanup on copy error

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAo ZhouApr 22, 2026Fixed in 6.18.27via kernel-cna
2 files changed · +0 10
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index 00dbcd4d28e680..34d9333e4229f3 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index 00dbcd4d28e680..34d9333e4229f3 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
8141a2dc7008

net: rds: fix MR cleanup on copy error

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAo ZhouApr 22, 2026Fixed in 7.1-rc1via kernel-cna
2 files changed · +0 10
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index aa6465dc742c2d..61fb6e45281bf1 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index aa6465dc742c2d..61fb6e45281bf1 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
033370ffb3c9

net: rds: fix MR cleanup on copy error

2 files changed · +0 10
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index 00dbcd4d28e680..34d9333e4229f3 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index 00dbcd4d28e680..34d9333e4229f3 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
d95cea9298be

net: rds: fix MR cleanup on copy error

2 files changed · +0 10
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index 00dbcd4d28e680..34d9333e4229f3 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index 00dbcd4d28e680..34d9333e4229f3 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
8141a2dc7008

net: rds: fix MR cleanup on copy error

2 files changed · +0 10
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index aa6465dc742c2d..61fb6e45281bf1 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index aa6465dc742c2d..61fb6e45281bf1 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
8fdbb6262a4a

net: rds: fix MR cleanup on copy error

2 files changed · +0 10
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index 00dbcd4d28e680..34d9333e4229f3 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index 00dbcd4d28e680..34d9333e4229f3 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
b3cb8cae530b

net: rds: fix MR cleanup on copy error

2 files changed · +0 10
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index aa6465dc742c2d..61fb6e45281bf1 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    
  • net/rds/rdma.c+0 5 modified
    diff --git a/net/rds/rdma.c b/net/rds/rdma.c
    index aa6465dc742c2d..61fb6e45281bf1 100644
    --- a/net/rds/rdma.c
    +++ b/net/rds/rdma.c
    @@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
     
     	if (args->cookie_addr &&
     	    put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
    -		if (!need_odp) {
    -			unpin_user_pages(pages, nr_pages);
    -			kfree(sg);
    -		}
     		ret = -EFAULT;
     		goto out;
     	}
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Double-free of pages and scatter-gather list in __rds_rdma_map() when put_user() fails after get_mr() has transferred ownership to the transport."

Attack vector

An attacker with access to the RDS RDMA interface can trigger a use-after-free / double-free by invoking `__rds_rdma_map()` and arranging for the `put_user()` call that copies the MR cookie back to userspace to fail (e.g., by passing an invalid `cookie_addr` pointer). After `get_mr()` succeeds, ownership of the scatter-gather list and pages has been transferred to the transport. The old error path then freed those resources a second time, while the transport still held references, leading to memory corruption.

Affected code

The vulnerability is in the `__rds_rdma_map()` function in `net/rds/rdma.c` [patch_id=2660099]. The faulty code path is the `put_user()` failure branch at line 326, which unconditionally calls `unpin_user_pages(pages, nr_pages)` and `kfree(sg)` when `need_odp` is false.

What the fix does

The patch removes the three lines in the `put_user()` failure branch that called `unpin_user_pages(pages, nr_pages)` and `kfree(sg)` when `need_odp` was false [patch_id=2660099]. After `get_mr()` succeeds, the transport owns the pages and sg list, so the error path must not unpin or free them. Instead, the code now simply sets `ret = -EFAULT` and jumps to the `out` label, where the existing final cleanup path handles MR teardown correctly through `rds_rdma_drop_mr_refs()` and related logic.

Preconditions

  • inputAttacker must be able to invoke the RDS RDMA mapping ioctl (__rds_rdma_map) with a cookie_addr that causes put_user() to fail
  • configThe system must have the RDS protocol module loaded and RDMA transport configured

Generated on May 27, 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.