From 11a143f41d06e3a924ac64e136399bcf437e4032 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 22 Aug 2025 10:25:58 +0200 Subject: [PATCH] 6.6-stable patches added patches: mm-drop-the-assumption-that-vm_shared-always-implies-writable.patch mm-reinstate-ability-to-map-write-sealed-memfd-mappings-read-only.patch mm-update-memfd-seal-write-check-to-include-f_seal_write.patch selftests-memfd-add-test-for-mapping-write-sealed-memfd-read-only.patch --- ...at-vm_shared-always-implies-writable.patch | 206 +++++++++++++++ ...rite-sealed-memfd-mappings-read-only.patch | 236 ++++++++++++++++++ ...-write-check-to-include-f_seal_write.patch | 106 ++++++++ ...mapping-write-sealed-memfd-read-only.patch | 100 ++++++++ queue-6.6/series | 4 + 5 files changed, 652 insertions(+) create mode 100644 queue-6.6/mm-drop-the-assumption-that-vm_shared-always-implies-writable.patch create mode 100644 queue-6.6/mm-reinstate-ability-to-map-write-sealed-memfd-mappings-read-only.patch create mode 100644 queue-6.6/mm-update-memfd-seal-write-check-to-include-f_seal_write.patch create mode 100644 queue-6.6/selftests-memfd-add-test-for-mapping-write-sealed-memfd-read-only.patch diff --git a/queue-6.6/mm-drop-the-assumption-that-vm_shared-always-implies-writable.patch b/queue-6.6/mm-drop-the-assumption-that-vm_shared-always-implies-writable.patch new file mode 100644 index 0000000000..d492cb372e --- /dev/null +++ b/queue-6.6/mm-drop-the-assumption-that-vm_shared-always-implies-writable.patch @@ -0,0 +1,206 @@ +From stable+bounces-165159-greg=kroah.com@vger.kernel.org Wed Jul 30 03:52:26 2025 +From: "Isaac J. Manjarres" +Date: Tue, 29 Jul 2025 18:51:45 -0700 +Subject: mm: drop the assumption that VM_SHARED always implies writable +To: lorenzo.stoakes@oracle.com, gregkh@linuxfoundation.org, Alexander Viro , Christian Brauner , Jan Kara , Andrew Morton , David Hildenbrand , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Kees Cook , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Valentin Schneider , "Matthew Wilcox (Oracle)" , Jann Horn , Pedro Falcato +Cc: aliceryhl@google.com, stable@vger.kernel.org, "Isaac J. Manjarres" , kernel-team@android.com, Lorenzo Stoakes , Andy Lutomirski , Hugh Dickins , Mike Kravetz , Muchun Song , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org +Message-ID: <20250730015152.29758-2-isaacmanjarres@google.com> + +From: "Isaac J. Manjarres" + +From: Lorenzo Stoakes + +[ Upstream commit e8e17ee90eaf650c855adb0a3e5e965fd6692ff1 ] + +Patch series "permit write-sealed memfd read-only shared mappings", v4. + +The man page for fcntl() describing memfd file seals states the following +about F_SEAL_WRITE:- + + Furthermore, trying to create new shared, writable memory-mappings via + mmap(2) will also fail with EPERM. + +With emphasis on 'writable'. In turns out in fact that currently the +kernel simply disallows all new shared memory mappings for a memfd with +F_SEAL_WRITE applied, rendering this documentation inaccurate. + +This matters because users are therefore unable to obtain a shared mapping +to a memfd after write sealing altogether, which limits their usefulness. +This was reported in the discussion thread [1] originating from a bug +report [2]. + +This is a product of both using the struct address_space->i_mmap_writable +atomic counter to determine whether writing may be permitted, and the +kernel adjusting this counter when any VM_SHARED mapping is performed and +more generally implicitly assuming VM_SHARED implies writable. + +It seems sensible that we should only update this mapping if VM_MAYWRITE +is specified, i.e. whether it is possible that this mapping could at any +point be written to. + +If we do so then all we need to do to permit write seals to function as +documented is to clear VM_MAYWRITE when mapping read-only. It turns out +this functionality already exists for F_SEAL_FUTURE_WRITE - we can +therefore simply adapt this logic to do the same for F_SEAL_WRITE. + +We then hit a chicken and egg situation in mmap_region() where the check +for VM_MAYWRITE occurs before we are able to clear this flag. To work +around this, perform this check after we invoke call_mmap(), with careful +consideration of error paths. + +Thanks to Andy Lutomirski for the suggestion! + +[1]:https://lore.kernel.org/all/20230324133646.16101dfa666f253c4715d965@linux-foundation.org/ +[2]:https://bugzilla.kernel.org/show_bug.cgi?id=217238 + +This patch (of 3): + +There is a general assumption that VMAs with the VM_SHARED flag set are +writable. If the VM_MAYWRITE flag is not set, then this is simply not the +case. + +Update those checks which affect the struct address_space->i_mmap_writable +field to explicitly test for this by introducing +[vma_]is_shared_maywrite() helper functions. + +This remains entirely conservative, as the lack of VM_MAYWRITE guarantees +that the VMA cannot be written to. + +Link: https://lkml.kernel.org/r/cover.1697116581.git.lstoakes@gmail.com +Link: https://lkml.kernel.org/r/d978aefefa83ec42d18dfa964ad180dbcde34795.1697116581.git.lstoakes@gmail.com +Signed-off-by: Lorenzo Stoakes +Suggested-by: Andy Lutomirski +Reviewed-by: Jan Kara +Cc: Alexander Viro +Cc: Christian Brauner +Cc: Hugh Dickins +Cc: Matthew Wilcox (Oracle) +Cc: Mike Kravetz +Cc: Muchun Song +Signed-off-by: Andrew Morton +Cc: stable@vger.kernel.org +[isaacmanjarres: resolved merge conflicts due to +due to refactoring that happened in upstream commit +5de195060b2e ("mm: resolve faulty mmap_region() error path behaviour")] +Signed-off-by: Isaac J. Manjarres +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/fs.h | 4 ++-- + include/linux/mm.h | 11 +++++++++++ + kernel/fork.c | 2 +- + mm/filemap.c | 2 +- + mm/madvise.c | 2 +- + mm/mmap.c | 8 ++++---- + 6 files changed, 20 insertions(+), 9 deletions(-) + +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -456,7 +456,7 @@ extern const struct address_space_operat + * It is also used to block modification of page cache contents through + * memory mappings. + * @gfp_mask: Memory allocation flags to use for allocating pages. +- * @i_mmap_writable: Number of VM_SHARED mappings. ++ * @i_mmap_writable: Number of VM_SHARED, VM_MAYWRITE mappings. + * @nr_thps: Number of THPs in the pagecache (non-shmem only). + * @i_mmap: Tree of private and shared mappings. + * @i_mmap_rwsem: Protects @i_mmap and @i_mmap_writable. +@@ -559,7 +559,7 @@ static inline int mapping_mapped(struct + + /* + * Might pages of this file have been modified in userspace? +- * Note that i_mmap_writable counts all VM_SHARED vmas: do_mmap ++ * Note that i_mmap_writable counts all VM_SHARED, VM_MAYWRITE vmas: do_mmap + * marks vma as VM_SHARED if it is shared, and the file was opened for + * writing i.e. vma may be mprotected writable even if now readonly. + * +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -941,6 +941,17 @@ static inline bool vma_is_accessible(str + return vma->vm_flags & VM_ACCESS_FLAGS; + } + ++static inline bool is_shared_maywrite(vm_flags_t vm_flags) ++{ ++ return (vm_flags & (VM_SHARED | VM_MAYWRITE)) == ++ (VM_SHARED | VM_MAYWRITE); ++} ++ ++static inline bool vma_is_shared_maywrite(struct vm_area_struct *vma) ++{ ++ return is_shared_maywrite(vma->vm_flags); ++} ++ + static inline + struct vm_area_struct *vma_find(struct vma_iterator *vmi, unsigned long max) + { +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -739,7 +739,7 @@ static __latent_entropy int dup_mmap(str + + get_file(file); + i_mmap_lock_write(mapping); +- if (tmp->vm_flags & VM_SHARED) ++ if (vma_is_shared_maywrite(tmp)) + mapping_allow_writable(mapping); + flush_dcache_mmap_lock(mapping); + /* insert tmp into the share list, just after mpnt */ +--- a/mm/filemap.c ++++ b/mm/filemap.c +@@ -3716,7 +3716,7 @@ int generic_file_mmap(struct file *file, + */ + int generic_file_readonly_mmap(struct file *file, struct vm_area_struct *vma) + { +- if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) ++ if (vma_is_shared_maywrite(vma)) + return -EINVAL; + return generic_file_mmap(file, vma); + } +--- a/mm/madvise.c ++++ b/mm/madvise.c +@@ -987,7 +987,7 @@ static long madvise_remove(struct vm_are + return -EINVAL; + } + +- if ((vma->vm_flags & (VM_SHARED|VM_WRITE)) != (VM_SHARED|VM_WRITE)) ++ if (!vma_is_shared_maywrite(vma)) + return -EACCES; + + offset = (loff_t)(start - vma->vm_start) +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -107,7 +107,7 @@ void vma_set_page_prot(struct vm_area_st + static void __remove_shared_vm_struct(struct vm_area_struct *vma, + struct file *file, struct address_space *mapping) + { +- if (vma->vm_flags & VM_SHARED) ++ if (vma_is_shared_maywrite(vma)) + mapping_unmap_writable(mapping); + + flush_dcache_mmap_lock(mapping); +@@ -383,7 +383,7 @@ static unsigned long count_vma_pages_ran + static void __vma_link_file(struct vm_area_struct *vma, + struct address_space *mapping) + { +- if (vma->vm_flags & VM_SHARED) ++ if (vma_is_shared_maywrite(vma)) + mapping_allow_writable(mapping); + + flush_dcache_mmap_lock(mapping); +@@ -2845,7 +2845,7 @@ cannot_expand: + mm->map_count++; + if (vma->vm_file) { + i_mmap_lock_write(vma->vm_file->f_mapping); +- if (vma->vm_flags & VM_SHARED) ++ if (vma_is_shared_maywrite(vma)) + mapping_allow_writable(vma->vm_file->f_mapping); + + flush_dcache_mmap_lock(vma->vm_file->f_mapping); +@@ -2926,7 +2926,7 @@ unsigned long mmap_region(struct file *f + return -EINVAL; + + /* Map writable and ensure this isn't a sealed memfd. */ +- if (file && (vm_flags & VM_SHARED)) { ++ if (file && is_shared_maywrite(vm_flags)) { + int error = mapping_map_writable(file->f_mapping); + + if (error) diff --git a/queue-6.6/mm-reinstate-ability-to-map-write-sealed-memfd-mappings-read-only.patch b/queue-6.6/mm-reinstate-ability-to-map-write-sealed-memfd-mappings-read-only.patch new file mode 100644 index 0000000000..5be9708b07 --- /dev/null +++ b/queue-6.6/mm-reinstate-ability-to-map-write-sealed-memfd-mappings-read-only.patch @@ -0,0 +1,236 @@ +From stable+bounces-165161-greg=kroah.com@vger.kernel.org Wed Jul 30 03:52:59 2025 +From: "Isaac J. Manjarres" +Date: Tue, 29 Jul 2025 18:51:47 -0700 +Subject: mm: reinstate ability to map write-sealed memfd mappings read-only +To: lorenzo.stoakes@oracle.com, gregkh@linuxfoundation.org, Hugh Dickins , Baolin Wang , Andrew Morton , David Hildenbrand , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Jann Horn , Pedro Falcato +Cc: aliceryhl@google.com, stable@vger.kernel.org, "Isaac J. Manjarres" , kernel-team@android.com, Julian Orth , "Liam R. Howlett" , Linus Torvalds , Shuah Khan , linux-mm@kvack.org, linux-kernel@vger.kernel.org +Message-ID: <20250730015152.29758-4-isaacmanjarres@google.com> + +From: "Isaac J. Manjarres" + +From: Lorenzo Stoakes + +[ Upstream commit 8ec396d05d1b737c87311fb7311f753b02c2a6b1 ] + +Patch series "mm: reinstate ability to map write-sealed memfd mappings +read-only". + +In commit 158978945f31 ("mm: perform the mapping_map_writable() check +after call_mmap()") (and preceding changes in the same series) it became +possible to mmap() F_SEAL_WRITE sealed memfd mappings read-only. + +Commit 5de195060b2e ("mm: resolve faulty mmap_region() error path +behaviour") unintentionally undid this logic by moving the +mapping_map_writable() check before the shmem_mmap() hook is invoked, +thereby regressing this change. + +This series reworks how we both permit write-sealed mappings being mapped +read-only and disallow mprotect() from undoing the write-seal, fixing this +regression. + +We also add a regression test to ensure that we do not accidentally +regress this in future. + +Thanks to Julian Orth for reporting this regression. + +This patch (of 2): + +In commit 158978945f31 ("mm: perform the mapping_map_writable() check +after call_mmap()") (and preceding changes in the same series) it became +possible to mmap() F_SEAL_WRITE sealed memfd mappings read-only. + +This was previously unnecessarily disallowed, despite the man page +documentation indicating that it would be, thereby limiting the usefulness +of F_SEAL_WRITE logic. + +We fixed this by adapting logic that existed for the F_SEAL_FUTURE_WRITE +seal (one which disallows future writes to the memfd) to also be used for +F_SEAL_WRITE. + +For background - the F_SEAL_FUTURE_WRITE seal clears VM_MAYWRITE for a +read-only mapping to disallow mprotect() from overriding the seal - an +operation performed by seal_check_write(), invoked from shmem_mmap(), the +f_op->mmap() hook used by shmem mappings. + +By extending this to F_SEAL_WRITE and critically - checking +mapping_map_writable() to determine if we may map the memfd AFTER we +invoke shmem_mmap() - the desired logic becomes possible. This is because +mapping_map_writable() explicitly checks for VM_MAYWRITE, which we will +have cleared. + +Commit 5de195060b2e ("mm: resolve faulty mmap_region() error path +behaviour") unintentionally undid this logic by moving the +mapping_map_writable() check before the shmem_mmap() hook is invoked, +thereby regressing this change. + +We reinstate this functionality by moving the check out of shmem_mmap() +and instead performing it in do_mmap() at the point at which VMA flags are +being determined, which seems in any case to be a more appropriate place +in which to make this determination. + +In order to achieve this we rework memfd seal logic to allow us access to +this information using existing logic and eliminate the clearing of +VM_MAYWRITE from seal_check_write() which we are performing in do_mmap() +instead. + +Link: https://lkml.kernel.org/r/99fc35d2c62bd2e05571cf60d9f8b843c56069e0.1732804776.git.lorenzo.stoakes@oracle.com +Fixes: 5de195060b2e ("mm: resolve faulty mmap_region() error path behaviour") +Signed-off-by: Lorenzo Stoakes +Reported-by: Julian Orth +Closes: https://lore.kernel.org/all/CAHijbEUMhvJTN9Xw1GmbM266FXXv=U7s4L_Jem5x3AaPZxrYpQ@mail.gmail.com/ +Cc: Jann Horn +Cc: Liam R. Howlett +Cc: Linus Torvalds +Cc: Shuah Khan +Cc: Vlastimil Babka +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Isaac J. Manjarres +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/memfd.h | 14 ++++++++++++ + include/linux/mm.h | 58 ++++++++++++++++++++++++++++++++++---------------- + mm/memfd.c | 2 - + mm/mmap.c | 4 +++ + 4 files changed, 59 insertions(+), 19 deletions(-) + +--- a/include/linux/memfd.h ++++ b/include/linux/memfd.h +@@ -6,11 +6,25 @@ + + #ifdef CONFIG_MEMFD_CREATE + extern long memfd_fcntl(struct file *file, unsigned int cmd, unsigned int arg); ++unsigned int *memfd_file_seals_ptr(struct file *file); + #else + static inline long memfd_fcntl(struct file *f, unsigned int c, unsigned int a) + { + return -EINVAL; + } ++ ++static inline unsigned int *memfd_file_seals_ptr(struct file *file) ++{ ++ return NULL; ++} + #endif + ++/* Retrieve memfd seals associated with the file, if any. */ ++static inline unsigned int memfd_file_seals(struct file *file) ++{ ++ unsigned int *sealsp = memfd_file_seals_ptr(file); ++ ++ return sealsp ? *sealsp : 0; ++} ++ + #endif /* __LINUX_MEMFD_H */ +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -4022,6 +4022,37 @@ void mem_dump_obj(void *object); + static inline void mem_dump_obj(void *object) {} + #endif + ++static inline bool is_write_sealed(int seals) ++{ ++ return seals & (F_SEAL_WRITE | F_SEAL_FUTURE_WRITE); ++} ++ ++/** ++ * is_readonly_sealed - Checks whether write-sealed but mapped read-only, ++ * in which case writes should be disallowing moving ++ * forwards. ++ * @seals: the seals to check ++ * @vm_flags: the VMA flags to check ++ * ++ * Returns whether readonly sealed, in which case writess should be disallowed ++ * going forward. ++ */ ++static inline bool is_readonly_sealed(int seals, vm_flags_t vm_flags) ++{ ++ /* ++ * 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 ++ * VM_MAYWRITE as we still want them to be COW-writable. ++ */ ++ if (is_write_sealed(seals) && ++ ((vm_flags & (VM_SHARED | VM_WRITE)) == VM_SHARED)) ++ return true; ++ ++ return false; ++} ++ + /** + * seal_check_write - Check for F_SEAL_WRITE or F_SEAL_FUTURE_WRITE flags and + * handle them. +@@ -4033,24 +4064,15 @@ static inline void mem_dump_obj(void *ob + */ + static inline int seal_check_write(int seals, struct vm_area_struct *vma) + { +- if (seals & (F_SEAL_WRITE | F_SEAL_FUTURE_WRITE)) { +- /* +- * New PROT_WRITE and MAP_SHARED mmaps are not allowed when +- * 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 +- * 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 +- * VM_MAYWRITE as we still want them to be COW-writable. +- */ +- if (vma->vm_flags & VM_SHARED) +- vm_flags_clear(vma, VM_MAYWRITE); +- } ++ if (!is_write_sealed(seals)) ++ return 0; ++ ++ /* ++ * New PROT_WRITE and MAP_SHARED mmaps are not allowed when ++ * write seals are active. ++ */ ++ if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_WRITE)) ++ return -EPERM; + + return 0; + } +--- a/mm/memfd.c ++++ b/mm/memfd.c +@@ -134,7 +134,7 @@ static int memfd_wait_for_pins(struct ad + return error; + } + +-static unsigned int *memfd_file_seals_ptr(struct file *file) ++unsigned int *memfd_file_seals_ptr(struct file *file) + { + if (shmem_file(file)) + return &SHMEM_I(file_inode(file))->seals; +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -47,6 +47,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -1285,6 +1286,7 @@ unsigned long do_mmap(struct file *file, + + if (file) { + struct inode *inode = file_inode(file); ++ unsigned int seals = memfd_file_seals(file); + unsigned long flags_mask; + + if (!file_mmap_ok(file, inode, pgoff, len)) +@@ -1323,6 +1325,8 @@ unsigned long do_mmap(struct file *file, + vm_flags |= VM_SHARED | VM_MAYSHARE; + if (!(file->f_mode & FMODE_WRITE)) + vm_flags &= ~(VM_MAYWRITE | VM_SHARED); ++ else if (is_readonly_sealed(seals, vm_flags)) ++ vm_flags &= ~VM_MAYWRITE; + fallthrough; + case MAP_PRIVATE: + if (!(file->f_mode & FMODE_READ)) diff --git a/queue-6.6/mm-update-memfd-seal-write-check-to-include-f_seal_write.patch b/queue-6.6/mm-update-memfd-seal-write-check-to-include-f_seal_write.patch new file mode 100644 index 0000000000..8f0315071c --- /dev/null +++ b/queue-6.6/mm-update-memfd-seal-write-check-to-include-f_seal_write.patch @@ -0,0 +1,106 @@ +From stable+bounces-165160-greg=kroah.com@vger.kernel.org Wed Jul 30 03:52:41 2025 +From: "Isaac J. Manjarres" +Date: Tue, 29 Jul 2025 18:51:46 -0700 +Subject: mm: update memfd seal write check to include F_SEAL_WRITE +To: lorenzo.stoakes@oracle.com, gregkh@linuxfoundation.org, Muchun Song , Oscar Salvador , David Hildenbrand , Andrew Morton , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Hugh Dickins , Baolin Wang +Cc: aliceryhl@google.com, stable@vger.kernel.org, "Isaac J. Manjarres" , kernel-team@android.com, Lorenzo Stoakes , Jan Kara , Alexander Viro , Andy Lutomirski , Christian Brauner , "Matthew Wilcox (Oracle)" , Mike Kravetz , linux-mm@kvack.org, linux-kernel@vger.kernel.org +Message-ID: <20250730015152.29758-3-isaacmanjarres@google.com> + +From: "Isaac J. Manjarres" + +From: Lorenzo Stoakes + +[ 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: Lorenzo Stoakes +Reviewed-by: Jan Kara +Cc: Alexander Viro +Cc: Andy Lutomirski +Cc: Christian Brauner +Cc: Hugh Dickins +Cc: Matthew Wilcox (Oracle) +Cc: Mike Kravetz +Cc: Muchun Song +Signed-off-by: Andrew Morton +Cc: stable@vger.kernel.org +Signed-off-by: Isaac J. Manjarres +Signed-off-by: Greg Kroah-Hartman +--- + fs/hugetlbfs/inode.c | 2 +- + include/linux/mm.h | 15 ++++++++------- + mm/shmem.c | 2 +- + 3 files changed, 10 insertions(+), 9 deletions(-) + +--- a/fs/hugetlbfs/inode.c ++++ b/fs/hugetlbfs/inode.c +@@ -136,7 +136,7 @@ static int hugetlbfs_file_mmap(struct fi + vm_flags_set(vma, 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; + +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -4023,25 +4023,26 @@ static inline void mem_dump_obj(void *ob + #endif + + /** +- * 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 +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -2396,7 +2396,7 @@ static int shmem_mmap(struct file *file, + struct shmem_inode_info *info = SHMEM_I(inode); + int ret; + +- ret = seal_check_future_write(info->seals, vma); ++ ret = seal_check_write(info->seals, vma); + if (ret) + return ret; + diff --git a/queue-6.6/selftests-memfd-add-test-for-mapping-write-sealed-memfd-read-only.patch b/queue-6.6/selftests-memfd-add-test-for-mapping-write-sealed-memfd-read-only.patch new file mode 100644 index 0000000000..a2b69ab842 --- /dev/null +++ b/queue-6.6/selftests-memfd-add-test-for-mapping-write-sealed-memfd-read-only.patch @@ -0,0 +1,100 @@ +From stable+bounces-165162-greg=kroah.com@vger.kernel.org Wed Jul 30 03:53:04 2025 +From: "Isaac J. Manjarres" +Date: Tue, 29 Jul 2025 18:51:48 -0700 +Subject: selftests/memfd: add test for mapping write-sealed memfd read-only +To: lorenzo.stoakes@oracle.com, gregkh@linuxfoundation.org, Shuah Khan +Cc: aliceryhl@google.com, surenb@google.com, stable@vger.kernel.org, "Isaac J. Manjarres" , kernel-team@android.com, Jann Horn , Julian Orth , "Liam R. Howlett" , Linus Torvalds , Vlastimil Babka , Andrew Morton , linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org +Message-ID: <20250730015152.29758-5-isaacmanjarres@google.com> + +From: "Isaac J. Manjarres" + +From: Lorenzo Stoakes + +[ Upstream commit ea0916e01d0b0f2cce1369ac1494239a79827270 ] + +Now we have reinstated the ability to map F_SEAL_WRITE mappings read-only, +assert that we are able to do this in a test to ensure that we do not +regress this again. + +Link: https://lkml.kernel.org/r/a6377ec470b14c0539b4600cf8fa24bf2e4858ae.1732804776.git.lorenzo.stoakes@oracle.com +Signed-off-by: Lorenzo Stoakes +Cc: Jann Horn +Cc: Julian Orth +Cc: Liam R. Howlett +Cc: Linus Torvalds +Cc: Shuah Khan +Cc: Vlastimil Babka +Signed-off-by: Andrew Morton +Cc: stable@vger.kernel.org +Signed-off-by: Isaac J. Manjarres +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/memfd/memfd_test.c | 43 +++++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +--- a/tools/testing/selftests/memfd/memfd_test.c ++++ b/tools/testing/selftests/memfd/memfd_test.c +@@ -285,6 +285,24 @@ static void *mfd_assert_mmap_shared(int + return p; + } + ++static void *mfd_assert_mmap_read_shared(int fd) ++{ ++ void *p; ++ ++ p = mmap(NULL, ++ mfd_def_size, ++ PROT_READ, ++ MAP_SHARED, ++ fd, ++ 0); ++ if (p == MAP_FAILED) { ++ printf("mmap() failed: %m\n"); ++ abort(); ++ } ++ ++ return p; ++} ++ + static void *mfd_assert_mmap_private(int fd) + { + void *p; +@@ -986,6 +1004,30 @@ static void test_seal_future_write(void) + close(fd); + } + ++static void test_seal_write_map_read_shared(void) ++{ ++ int fd; ++ void *p; ++ ++ printf("%s SEAL-WRITE-MAP-READ\n", memfd_str); ++ ++ fd = mfd_assert_new("kern_memfd_seal_write_map_read", ++ mfd_def_size, ++ MFD_CLOEXEC | MFD_ALLOW_SEALING); ++ ++ mfd_assert_add_seals(fd, F_SEAL_WRITE); ++ mfd_assert_has_seals(fd, F_SEAL_WRITE); ++ ++ p = mfd_assert_mmap_read_shared(fd); ++ ++ mfd_assert_read(fd); ++ mfd_assert_read_shared(fd); ++ mfd_fail_write(fd); ++ ++ munmap(p, mfd_def_size); ++ close(fd); ++} ++ + /* + * Test SEAL_SHRINK + * Test whether SEAL_SHRINK actually prevents shrinking +@@ -1603,6 +1645,7 @@ int main(int argc, char **argv) + + test_seal_write(); + test_seal_future_write(); ++ test_seal_write_map_read_shared(); + test_seal_shrink(); + test_seal_grow(); + test_seal_resize(); diff --git a/queue-6.6/series b/queue-6.6/series index 88e9f71d5b..c7a0a7b6b4 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -425,3 +425,7 @@ ipv6-sr-fix-mac-comparison-to-be-constant-time.patch acpi-pfr_update-fix-the-driver-update-version-check.patch mptcp-drop-skb-if-mptcp-skb-extension-allocation-fails.patch mptcp-pm-kernel-flush-do-not-reset-add_addr-limit.patch +mm-drop-the-assumption-that-vm_shared-always-implies-writable.patch +mm-update-memfd-seal-write-check-to-include-f_seal_write.patch +mm-reinstate-ability-to-map-write-sealed-memfd-mappings-read-only.patch +selftests-memfd-add-test-for-mapping-write-sealed-memfd-read-only.patch -- 2.47.3