Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55933e95 authored by Lorenzo Stoakes's avatar Lorenzo Stoakes Committed by Greg Kroah-Hartman
Browse files

mm: update memfd seal write check to include F_SEAL_WRITE

[ Upstream commit 28464bbb2ddc199433383994bcb9600c8034afa1 ]

The seal_check_future_write() function is called by shmem_mmap() or
hugetlbfs_file_mmap() to disallow any future writable mappings of an memfd
sealed this way.

The F_SEAL_WRITE flag is not checked here, as that is handled via the
mapping->i_mmap_writable mechanism and so any attempt at a mapping would
fail before this could be run.

However we intend to change this, meaning this check can be performed for
F_SEAL_WRITE mappings also.

The logic here is equally applicable to both flags, so update this
function to accommodate both and rename it accordingly.

Link: https://lkml.kernel.org/r/913628168ce6cce77df7d13a63970bae06a526e0.1697116581.git.lstoakes@gmail.com


Signed-off-by: default avatarLorenzo Stoakes <lstoakes@gmail.com>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Muchun Song <muchun.song@linux.dev>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarIsaac J. Manjarres <isaacmanjarres@google.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6a8b539c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -152,7 +152,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
	vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND;
	vma->vm_ops = &hugetlb_vm_ops;

	ret = seal_check_future_write(info->seals, vma);
	ret = seal_check_write(info->seals, vma);
	if (ret)
		return ret;

+8 −7
Original line number Diff line number Diff line
@@ -2946,25 +2946,26 @@ static inline int pages_identical(struct page *page1, struct page *page2)
}

/**
 * seal_check_future_write - Check for F_SEAL_FUTURE_WRITE flag and handle it
 * seal_check_write - Check for F_SEAL_WRITE or F_SEAL_FUTURE_WRITE flags and
 *                    handle them.
 * @seals: the seals to check
 * @vma: the vma to operate on
 *
 * Check whether F_SEAL_FUTURE_WRITE is set; if so, do proper check/handling on
 * the vma flags.  Return 0 if check pass, or <0 for errors.
 * Check whether F_SEAL_WRITE or F_SEAL_FUTURE_WRITE are set; if so, do proper
 * check/handling on the vma flags.  Return 0 if check pass, or <0 for errors.
 */
static inline int seal_check_future_write(int seals, struct vm_area_struct *vma)
static inline int seal_check_write(int seals, struct vm_area_struct *vma)
{
	if (seals & F_SEAL_FUTURE_WRITE) {
	if (seals & (F_SEAL_WRITE | F_SEAL_FUTURE_WRITE)) {
		/*
		 * New PROT_WRITE and MAP_SHARED mmaps are not allowed when
		 * "future write" seal active.
		 * write seals are active.
		 */
		if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_WRITE))
			return -EPERM;

		/*
		 * Since an F_SEAL_FUTURE_WRITE sealed memfd can be mapped as
		 * Since an F_SEAL_[FUTURE_]WRITE sealed memfd can be mapped as
		 * MAP_SHARED and read-only, take care to not allow mprotect to
		 * revert protections on such mappings. Do this only for shared
		 * mappings. For private mappings, don't need to mask
+1 −1
Original line number Diff line number Diff line
@@ -2215,7 +2215,7 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
	struct shmem_inode_info *info = SHMEM_I(file_inode(file));
	int ret;

	ret = seal_check_future_write(info->seals, vma);
	ret = seal_check_write(info->seals, vma);
	if (ret)
		return ret;