Re: [RFC PATCH 3/6] mm: nommu: fix an issue on map request to /dev/zero

Greg Kroah-Hartman <[email protected]>
Newsgroups gmane.linux.file-systems,gmane.linux.kernel.mm
Message-ID <2026081355-remold-sterility-84f9@gregkh>
On Thu, Aug 13, 2026 at 03:33:58PM +0900, Hajime Tazaki wrote:
> Upon a private file mapping request to /dev/zero, it calls
> kernel_read() in do_mmap_private(), getting a failure with the message
> like: "kernel reads not supported for file /dev/zero", which is because
> zero_fops defined in drivers/char/mem.c has both .read and .read_iter
> definitions.

Do you actually use a no-mmu system?

> Even fixing this issue, the map request to /dev/zero works fine without
> errors but the allocated vma isn't marked with anonymous because
> mmap_zero_prepare() isn't called under nommu platform, resulting
> vma_desc_set_anonymous() isn't called either.
> 
> This commit fixes those issues by:
> 1) use vfs_iter_read() instead to avoid failure at kernel_read()
> 2) calls .mmap_prepare on private mapping in do_mmap() so that required
>    preparations are done even in private mapping.
> 
> Cc: Arnd Bergmann <[email protected]>
> Cc: Greg Kroah-Hartman <[email protected]>
> Cc: "Matthew Wilcox (Oracle)" <[email protected]>
> Cc: Jan Kara <[email protected]>
> Cc: Andrew Morton <[email protected]>
> Cc: "Liam R. Howlett" <[email protected]>
> Cc: Lorenzo Stoakes <[email protected]>
> Cc: Vlastimil Babka <[email protected]>
> Cc: Jann Horn <[email protected]>
> Cc: Pedro Falcato <[email protected]>
> Cc: [email protected]
> Cc: [email protected] (open list:PAGE CACHE)
> Fixes: 4d03e3cc5982 ("fs: don't allow kernel reads and writes without iter ops")

Given the age of this issue, I don't think anyone uses no-mmu systems
anymore :(



> Assisted-by: cubic.dev:unspecified
> Signed-off-by: Hajime Tazaki <[email protected]>
> ---
>  drivers/char/mem.c |  5 ++-
>  mm/filemap.c       |  6 ++--
>  mm/nommu.c         | 84 ++++++++++++++++++++++++++++++++++++++++++++--
>  3 files changed, 87 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/char/mem.c b/drivers/char/mem.c
> index 63253d1de5d7..dba24d0a7b33 100644
> --- a/drivers/char/mem.c
> +++ b/drivers/char/mem.c
> @@ -500,11 +500,10 @@ static ssize_t read_zero(struct file *file, char __user *buf,
>  
>  static int mmap_zero_prepare(struct vm_area_desc *desc)
>  {
> -#ifndef CONFIG_MMU
> -	return -ENOSYS;
> -#endif
> +#ifdef CONFIG_MMU
>  	if (vma_desc_test(desc, VMA_SHARED_BIT))
>  		return shmem_zero_setup_desc(desc);
> +#endif
>  
>  	/*
>  	 * This is a highly unique situation where we mark a MAP_PRIVATE mapping
> diff --git a/mm/filemap.c b/mm/filemap.c
> index d721986d5f46..cf02faad86aa 100644
> --- a/mm/filemap.c
> +++ b/mm/filemap.c
> @@ -4077,7 +4077,7 @@ int generic_file_mmap(struct file *file, struct vm_area_struct *vma)
>  }
>  int generic_file_mmap_prepare(struct vm_area_desc *desc)
>  {
> -	return -ENOSYS;
> +	return 0;
>  }
>  int generic_file_readonly_mmap(struct file *file, struct vm_area_struct *vma)
>  {
> @@ -4085,7 +4085,9 @@ int generic_file_readonly_mmap(struct file *file, struct vm_area_struct *vma)
>  }
>  int generic_file_readonly_mmap_prepare(struct vm_area_desc *desc)
>  {
> -	return -ENOSYS;
> +	if (is_shared_maywrite(&desc->vma_flags))
> +		return -EINVAL;
> +	return generic_file_mmap_prepare(desc);
>  }
>  #endif /* CONFIG_MMU */
>  
> diff --git a/mm/nommu.c b/mm/nommu.c
> index e40990e15831..a29a53c1c80a 100644
> --- a/mm/nommu.c
> +++ b/mm/nommu.c
> @@ -37,6 +37,7 @@
>  
>  #include <linux/uaccess.h>
>  #include <linux/uio.h>
> +#include <linux/major.h>
>  #include <asm/tlb.h>
>  #include <asm/tlbflush.h>
>  #include <asm/mmu_context.h>
> @@ -856,6 +857,22 @@ static int validate_mmap_request(struct file *file,
>  	return 0;
>  }
>  
> +static int is_file_anonymous(struct file *file)
> +{
> +	if (!file)
> +		return 1;
> +
> +	if (file->f_path.dentry && file->f_path.dentry->d_inode) {
> +		struct inode *inode = file->f_path.dentry->d_inode;
> +		/* if the device is /dev/zero */
> +		if (S_ISCHR(inode->i_mode) &&
> +		    imajor(inode) == MEM_MAJOR && iminor(inode) == 5)
> +			return 1;
> +	}
> +
> +	return 0;
> +}
> +
>  /*
>   * we've determined that we can make the mapping, now translate what we
>   * now know into VMA flags
> @@ -869,7 +886,11 @@ static vm_flags_t determine_vm_flags(struct file *file,
>  
>  	vm_flags = calc_vm_prot_bits(prot, 0) | calc_vm_flag_bits(file, flags);
>  
> -	if (!file) {
> +	/* private and file mapping will be marked anonymous later (do_mmap_private()).
> +	 * and /dev/zero is marked by them at .mmap_prepare,
> +	 * which should be _before_ this point.
> +	 */

Wrong coding style for the comment, which is very typical of
LLM-generated stuff.  Always rewrite the output of these tools to
actually be sane.

thanks,

greg k-h
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.