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

CVE-2026-46100

CVE-2026-46100

Description

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

fs: afs: revert mmap_prepare() change

Partially reverts commit 9d5403b1036c ("fs: convert most other generic_file_*mmap() users to .mmap_prepare()").

This is because the .mmap invocation establishes a refcount, but .mmap_prepare is called at a point where a merge or an allocation failure might happen after the call, which would leak the refcount increment.

Functionality is being added to permit the use of .mmap_prepare in this case, but in the interim, we need to fix this.

Affected products

2

Patches

6
f51f85c04480

fs: afs: revert mmap_prepare() change

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"Lorenzo Stoakes (Oracle)"Mar 20, 2026Fixed in 6.18.27via kernel-cna
1 file changed · +6 7
  • fs/afs/file.c+6 7 modified
    diff --git a/fs/afs/file.c b/fs/afs/file.c
    index f66a9229428499..fc15497608c614 100644
    --- a/fs/afs/file.c
    +++ b/fs/afs/file.c
    @@ -19,7 +19,7 @@
     #include <trace/events/netfs.h>
     #include "internal.h"
     
    -static int afs_file_mmap_prepare(struct vm_area_desc *desc);
    +static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
     
     static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter);
     static ssize_t afs_file_splice_read(struct file *in, loff_t *ppos,
    @@ -35,7 +35,7 @@ const struct file_operations afs_file_operations = {
     	.llseek		= generic_file_llseek,
     	.read_iter	= afs_file_read_iter,
     	.write_iter	= netfs_file_write_iter,
    -	.mmap_prepare	= afs_file_mmap_prepare,
    +	.mmap		= afs_file_mmap,
     	.splice_read	= afs_file_splice_read,
     	.splice_write	= iter_file_splice_write,
     	.fsync		= afs_fsync,
    @@ -492,16 +492,16 @@ static void afs_drop_open_mmap(struct afs_vnode *vnode)
     /*
      * Handle setting up a memory mapping on an AFS file.
      */
    -static int afs_file_mmap_prepare(struct vm_area_desc *desc)
    +static int afs_file_mmap(struct file *file, struct vm_area_struct *vma)
     {
    -	struct afs_vnode *vnode = AFS_FS_I(file_inode(desc->file));
    +	struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
     	int ret;
     
     	afs_add_open_mmap(vnode);
     
    -	ret = generic_file_mmap_prepare(desc);
    +	ret = generic_file_mmap(file, vma);
     	if (ret == 0)
    -		desc->vm_ops = &afs_vm_ops;
    +		vma->vm_ops = &afs_vm_ops;
     	else
     		afs_drop_open_mmap(vnode);
     	return ret;
    -- 
    cgit 1.3-korg
    
    
    
48c7a0eaeea4

fs: afs: revert mmap_prepare() change

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"Lorenzo Stoakes (Oracle)"Mar 20, 2026Fixed in 7.0.4via kernel-cna
1 file changed · +6 7
  • fs/afs/file.c+6 7 modified
    diff --git a/fs/afs/file.c b/fs/afs/file.c
    index f609366fd2ac07..74d04af51ff4ae 100644
    --- a/fs/afs/file.c
    +++ b/fs/afs/file.c
    @@ -19,7 +19,7 @@
     #include <trace/events/netfs.h>
     #include "internal.h"
     
    -static int afs_file_mmap_prepare(struct vm_area_desc *desc);
    +static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
     
     static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter);
     static ssize_t afs_file_splice_read(struct file *in, loff_t *ppos,
    @@ -35,7 +35,7 @@ const struct file_operations afs_file_operations = {
     	.llseek		= generic_file_llseek,
     	.read_iter	= afs_file_read_iter,
     	.write_iter	= netfs_file_write_iter,
    -	.mmap_prepare	= afs_file_mmap_prepare,
    +	.mmap		= afs_file_mmap,
     	.splice_read	= afs_file_splice_read,
     	.splice_write	= iter_file_splice_write,
     	.fsync		= afs_fsync,
    @@ -492,16 +492,16 @@ static void afs_drop_open_mmap(struct afs_vnode *vnode)
     /*
      * Handle setting up a memory mapping on an AFS file.
      */
    -static int afs_file_mmap_prepare(struct vm_area_desc *desc)
    +static int afs_file_mmap(struct file *file, struct vm_area_struct *vma)
     {
    -	struct afs_vnode *vnode = AFS_FS_I(file_inode(desc->file));
    +	struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
     	int ret;
     
     	afs_add_open_mmap(vnode);
     
    -	ret = generic_file_mmap_prepare(desc);
    +	ret = generic_file_mmap(file, vma);
     	if (ret == 0)
    -		desc->vm_ops = &afs_vm_ops;
    +		vma->vm_ops = &afs_vm_ops;
     	else
     		afs_drop_open_mmap(vnode);
     	return ret;
    -- 
    cgit 1.3-korg
    
    
    
fbfc6578eaca

fs: afs: revert mmap_prepare() change

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"Lorenzo Stoakes (Oracle)"Mar 20, 2026Fixed in 7.1-rc1via kernel-cna
1 file changed · +6 7
  • fs/afs/file.c+6 7 modified
    diff --git a/fs/afs/file.c b/fs/afs/file.c
    index f609366fd2ac07..74d04af51ff4ae 100644
    --- a/fs/afs/file.c
    +++ b/fs/afs/file.c
    @@ -19,7 +19,7 @@
     #include <trace/events/netfs.h>
     #include "internal.h"
     
    -static int afs_file_mmap_prepare(struct vm_area_desc *desc);
    +static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
     
     static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter);
     static ssize_t afs_file_splice_read(struct file *in, loff_t *ppos,
    @@ -35,7 +35,7 @@ const struct file_operations afs_file_operations = {
     	.llseek		= generic_file_llseek,
     	.read_iter	= afs_file_read_iter,
     	.write_iter	= netfs_file_write_iter,
    -	.mmap_prepare	= afs_file_mmap_prepare,
    +	.mmap		= afs_file_mmap,
     	.splice_read	= afs_file_splice_read,
     	.splice_write	= iter_file_splice_write,
     	.fsync		= afs_fsync,
    @@ -492,16 +492,16 @@ static void afs_drop_open_mmap(struct afs_vnode *vnode)
     /*
      * Handle setting up a memory mapping on an AFS file.
      */
    -static int afs_file_mmap_prepare(struct vm_area_desc *desc)
    +static int afs_file_mmap(struct file *file, struct vm_area_struct *vma)
     {
    -	struct afs_vnode *vnode = AFS_FS_I(file_inode(desc->file));
    +	struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
     	int ret;
     
     	afs_add_open_mmap(vnode);
     
    -	ret = generic_file_mmap_prepare(desc);
    +	ret = generic_file_mmap(file, vma);
     	if (ret == 0)
    -		desc->vm_ops = &afs_vm_ops;
    +		vma->vm_ops = &afs_vm_ops;
     	else
     		afs_drop_open_mmap(vnode);
     	return ret;
    -- 
    cgit 1.3-korg
    
    
    
48c7a0eaeea4

fs: afs: revert mmap_prepare() change

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git"Lorenzo Stoakes (Oracle)"Mar 20, 2026via nvd-ref
1 file changed · +6 7
  • fs/afs/file.c+6 7 modified
    diff --git a/fs/afs/file.c b/fs/afs/file.c
    index f609366fd2ac07..74d04af51ff4ae 100644
    --- a/fs/afs/file.c
    +++ b/fs/afs/file.c
    @@ -19,7 +19,7 @@
     #include <trace/events/netfs.h>
     #include "internal.h"
     
    -static int afs_file_mmap_prepare(struct vm_area_desc *desc);
    +static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
     
     static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter);
     static ssize_t afs_file_splice_read(struct file *in, loff_t *ppos,
    @@ -35,7 +35,7 @@ const struct file_operations afs_file_operations = {
     	.llseek		= generic_file_llseek,
     	.read_iter	= afs_file_read_iter,
     	.write_iter	= netfs_file_write_iter,
    -	.mmap_prepare	= afs_file_mmap_prepare,
    +	.mmap		= afs_file_mmap,
     	.splice_read	= afs_file_splice_read,
     	.splice_write	= iter_file_splice_write,
     	.fsync		= afs_fsync,
    @@ -492,16 +492,16 @@ static void afs_drop_open_mmap(struct afs_vnode *vnode)
     /*
      * Handle setting up a memory mapping on an AFS file.
      */
    -static int afs_file_mmap_prepare(struct vm_area_desc *desc)
    +static int afs_file_mmap(struct file *file, struct vm_area_struct *vma)
     {
    -	struct afs_vnode *vnode = AFS_FS_I(file_inode(desc->file));
    +	struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
     	int ret;
     
     	afs_add_open_mmap(vnode);
     
    -	ret = generic_file_mmap_prepare(desc);
    +	ret = generic_file_mmap(file, vma);
     	if (ret == 0)
    -		desc->vm_ops = &afs_vm_ops;
    +		vma->vm_ops = &afs_vm_ops;
     	else
     		afs_drop_open_mmap(vnode);
     	return ret;
    -- 
    cgit 1.3-korg
    
    
    
f51f85c04480

fs: afs: revert mmap_prepare() change

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git"Lorenzo Stoakes (Oracle)"Mar 20, 2026via nvd-ref
1 file changed · +6 7
  • fs/afs/file.c+6 7 modified
    diff --git a/fs/afs/file.c b/fs/afs/file.c
    index f66a9229428499..fc15497608c614 100644
    --- a/fs/afs/file.c
    +++ b/fs/afs/file.c
    @@ -19,7 +19,7 @@
     #include <trace/events/netfs.h>
     #include "internal.h"
     
    -static int afs_file_mmap_prepare(struct vm_area_desc *desc);
    +static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
     
     static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter);
     static ssize_t afs_file_splice_read(struct file *in, loff_t *ppos,
    @@ -35,7 +35,7 @@ const struct file_operations afs_file_operations = {
     	.llseek		= generic_file_llseek,
     	.read_iter	= afs_file_read_iter,
     	.write_iter	= netfs_file_write_iter,
    -	.mmap_prepare	= afs_file_mmap_prepare,
    +	.mmap		= afs_file_mmap,
     	.splice_read	= afs_file_splice_read,
     	.splice_write	= iter_file_splice_write,
     	.fsync		= afs_fsync,
    @@ -492,16 +492,16 @@ static void afs_drop_open_mmap(struct afs_vnode *vnode)
     /*
      * Handle setting up a memory mapping on an AFS file.
      */
    -static int afs_file_mmap_prepare(struct vm_area_desc *desc)
    +static int afs_file_mmap(struct file *file, struct vm_area_struct *vma)
     {
    -	struct afs_vnode *vnode = AFS_FS_I(file_inode(desc->file));
    +	struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
     	int ret;
     
     	afs_add_open_mmap(vnode);
     
    -	ret = generic_file_mmap_prepare(desc);
    +	ret = generic_file_mmap(file, vma);
     	if (ret == 0)
    -		desc->vm_ops = &afs_vm_ops;
    +		vma->vm_ops = &afs_vm_ops;
     	else
     		afs_drop_open_mmap(vnode);
     	return ret;
    -- 
    cgit 1.3-korg
    
    
    
fbfc6578eaca

fs: afs: revert mmap_prepare() change

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git"Lorenzo Stoakes (Oracle)"Mar 20, 2026via nvd-ref
1 file changed · +6 7
  • fs/afs/file.c+6 7 modified
    diff --git a/fs/afs/file.c b/fs/afs/file.c
    index f609366fd2ac07..74d04af51ff4ae 100644
    --- a/fs/afs/file.c
    +++ b/fs/afs/file.c
    @@ -19,7 +19,7 @@
     #include <trace/events/netfs.h>
     #include "internal.h"
     
    -static int afs_file_mmap_prepare(struct vm_area_desc *desc);
    +static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
     
     static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter);
     static ssize_t afs_file_splice_read(struct file *in, loff_t *ppos,
    @@ -35,7 +35,7 @@ const struct file_operations afs_file_operations = {
     	.llseek		= generic_file_llseek,
     	.read_iter	= afs_file_read_iter,
     	.write_iter	= netfs_file_write_iter,
    -	.mmap_prepare	= afs_file_mmap_prepare,
    +	.mmap		= afs_file_mmap,
     	.splice_read	= afs_file_splice_read,
     	.splice_write	= iter_file_splice_write,
     	.fsync		= afs_fsync,
    @@ -492,16 +492,16 @@ static void afs_drop_open_mmap(struct afs_vnode *vnode)
     /*
      * Handle setting up a memory mapping on an AFS file.
      */
    -static int afs_file_mmap_prepare(struct vm_area_desc *desc)
    +static int afs_file_mmap(struct file *file, struct vm_area_struct *vma)
     {
    -	struct afs_vnode *vnode = AFS_FS_I(file_inode(desc->file));
    +	struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
     	int ret;
     
     	afs_add_open_mmap(vnode);
     
    -	ret = generic_file_mmap_prepare(desc);
    +	ret = generic_file_mmap(file, vma);
     	if (ret == 0)
    -		desc->vm_ops = &afs_vm_ops;
    +		vma->vm_ops = &afs_vm_ops;
     	else
     		afs_drop_open_mmap(vnode);
     	return ret;
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"The `.mmap_prepare` callback increments a refcount at a point where a subsequent VMA merge or allocation failure can cause the refcount to leak."

Attack vector

An attacker can trigger a refcount leak by invoking `mmap()` on an AFS file. The `.mmap_prepare` callback calls `afs_add_open_mmap()` which increments a refcount, but the kernel's VMA merge logic or an allocation failure can occur after `.mmap_prepare` returns and before the VMA is fully installed. If a merge or allocation failure happens, the refcount increment is never balanced by a corresponding decrement, causing a leak [patch_id=2659709]. No special privileges beyond the ability to `mmap` an AFS file are required.

Affected code

The vulnerability is in `fs/afs/file.c`, specifically in the `afs_file_mmap_prepare()` function (introduced by commit 9d5403b1036c) which was assigned to the `.mmap_prepare` file_operations hook. The patch reverts this by switching back to the original `.mmap` hook and the `afs_file_mmap()` function signature [patch_id=2659709].

What the fix does

The patch partially reverts commit 9d5403b1036c by changing the AFS file operations back from `.mmap_prepare = afs_file_mmap_prepare` to `.mmap = afs_file_mmap` [patch_id=2659709]. The function signature is restored to the original `afs_file_mmap(struct file *file, struct vm_area_struct *vma)` and calls `generic_file_mmap()` instead of `generic_file_mmap_prepare()`. This closes the refcount leak because the `.mmap` callback is invoked at a point in the VMA installation path where merge/allocation failures can no longer occur after the refcount is taken. The commit message notes that proper `.mmap_prepare` support will be added later.

Preconditions

  • inputThe attacker must be able to mmap() a file on an AFS filesystem.
  • configThe kernel must have the commit 9d5403b1036c applied (which introduced the .mmap_prepare hook for AFS).

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

References

3

News mentions

0

No linked articles in our index yet.