From 83714a817846ffc7702ee8a42c32df74daf0a2e4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 17 Mar 2025 07:59:03 +0100 Subject: [PATCH] 6.6-stable patches added patches: lib-buildid-handle-memfd_secret-files-in-build_id_parse.patch mm-split-critical-region-in-remap_file_pages-and-invoke-lsms-in-between.patch --- ...memfd_secret-files-in-build_id_parse.patch | 62 +++++++ ...ile_pages-and-invoke-lsms-in-between.patch | 163 ++++++++++++++++++ queue-6.6/series | 2 + 3 files changed, 227 insertions(+) create mode 100644 queue-6.6/lib-buildid-handle-memfd_secret-files-in-build_id_parse.patch create mode 100644 queue-6.6/mm-split-critical-region-in-remap_file_pages-and-invoke-lsms-in-between.patch diff --git a/queue-6.6/lib-buildid-handle-memfd_secret-files-in-build_id_parse.patch b/queue-6.6/lib-buildid-handle-memfd_secret-files-in-build_id_parse.patch new file mode 100644 index 0000000000..95ddcaa41f --- /dev/null +++ b/queue-6.6/lib-buildid-handle-memfd_secret-files-in-build_id_parse.patch @@ -0,0 +1,62 @@ +From 5ac9b4e935dfc6af41eee2ddc21deb5c36507a9f Mon Sep 17 00:00:00 2001 +From: Andrii Nakryiko +Date: Thu, 17 Oct 2024 10:47:13 -0700 +Subject: lib/buildid: Handle memfd_secret() files in build_id_parse() + +From: Andrii Nakryiko + +commit 5ac9b4e935dfc6af41eee2ddc21deb5c36507a9f upstream. + +>From memfd_secret(2) manpage: + + The memory areas backing the file created with memfd_secret(2) are + visible only to the processes that have access to the file descriptor. + The memory region is removed from the kernel page tables and only the + page tables of the processes holding the file descriptor map the + corresponding physical memory. (Thus, the pages in the region can't be + accessed by the kernel itself, so that, for example, pointers to the + region can't be passed to system calls.) + +We need to handle this special case gracefully in build ID fetching +code. Return -EFAULT whenever secretmem file is passed to build_id_parse() +family of APIs. Original report and repro can be found in [0]. + + [0] https://lore.kernel.org/bpf/ZwyG8Uro%2FSyTXAni@ly-workstation/ + +Fixes: de3ec364c3c3 ("lib/buildid: add single folio-based file reader abstraction") +Reported-by: Yi Lai +Suggested-by: Shakeel Butt +Signed-off-by: Andrii Nakryiko +Signed-off-by: Daniel Borkmann +Acked-by: Shakeel Butt +Link: https://lore.kernel.org/bpf/20241017175431.6183-A-hca@linux.ibm.com +Link: https://lore.kernel.org/bpf/20241017174713.2157873-1-andrii@kernel.org +[ Chen Linxuan: backport same logic without folio-based changes ] +Fixes: 88a16a130933 ("perf: Add build id data in mmap2 event") +Signed-off-by: Chen Linxuan +Signed-off-by: Greg Kroah-Hartman +--- + lib/buildid.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/lib/buildid.c ++++ b/lib/buildid.c +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + + #define BUILD_ID 3 + +@@ -157,6 +158,10 @@ int build_id_parse(struct vm_area_struct + if (!vma->vm_file) + return -EINVAL; + ++ /* reject secretmem folios created with memfd_secret() */ ++ if (vma_is_secretmem(vma)) ++ return -EFAULT; ++ + page = find_get_page(vma->vm_file->f_mapping, 0); + if (!page) + return -EFAULT; /* page not mapped */ diff --git a/queue-6.6/mm-split-critical-region-in-remap_file_pages-and-invoke-lsms-in-between.patch b/queue-6.6/mm-split-critical-region-in-remap_file_pages-and-invoke-lsms-in-between.patch new file mode 100644 index 0000000000..bbf4ed7a38 --- /dev/null +++ b/queue-6.6/mm-split-critical-region-in-remap_file_pages-and-invoke-lsms-in-between.patch @@ -0,0 +1,163 @@ +From 58a039e679fe72bd0efa8b2abe669a7914bb4429 Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" +Date: Fri, 18 Oct 2024 18:14:15 +0200 +Subject: mm: split critical region in remap_file_pages() and invoke LSMs in between + +From: Kirill A. Shutemov + +commit 58a039e679fe72bd0efa8b2abe669a7914bb4429 upstream. + +Commit ea7e2d5e49c0 ("mm: call the security_mmap_file() LSM hook in +remap_file_pages()") fixed a security issue, it added an LSM check when +trying to remap file pages, so that LSMs have the opportunity to evaluate +such action like for other memory operations such as mmap() and +mprotect(). + +However, that commit called security_mmap_file() inside the mmap_lock +lock, while the other calls do it before taking the lock, after commit +8b3ec6814c83 ("take security_mmap_file() outside of ->mmap_sem"). + +This caused lock inversion issue with IMA which was taking the mmap_lock +and i_mutex lock in the opposite way when the remap_file_pages() system +call was called. + +Solve the issue by splitting the critical region in remap_file_pages() in +two regions: the first takes a read lock of mmap_lock, retrieves the VMA +and the file descriptor associated, and calculates the 'prot' and 'flags' +variables; the second takes a write lock on mmap_lock, checks that the VMA +flags and the VMA file descriptor are the same as the ones obtained in the +first critical region (otherwise the system call fails), and calls +do_mmap(). + +In between, after releasing the read lock and before taking the write +lock, call security_mmap_file(), and solve the lock inversion issue. + +Link: https://lkml.kernel.org/r/20241018161415.3845146-1-roberto.sassu@huaweicloud.com +Fixes: ea7e2d5e49c0 ("mm: call the security_mmap_file() LSM hook in remap_file_pages()") +Signed-off-by: Kirill A. Shutemov +Signed-off-by: Roberto Sassu +Reported-by: syzbot+1cd571a672400ef3a930@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/linux-security-module/66f7b10e.050a0220.46d20.0036.GAE@google.com/ +Tested-by: Roberto Sassu +Reviewed-by: Roberto Sassu +Reviewed-by: Jann Horn +Reviewed-by: Lorenzo Stoakes +Reviewed-by: Liam R. Howlett +Reviewed-by: Paul Moore +Tested-by: syzbot+1cd571a672400ef3a930@syzkaller.appspotmail.com +Cc: Jarkko Sakkinen +Cc: Dmitry Kasatkin +Cc: Eric Snowberg +Cc: James Morris +Cc: Mimi Zohar +Cc: "Serge E. Hallyn" +Cc: Shu Han +Cc: Vlastimil Babka +Signed-off-by: Andrew Morton +Signed-off-by: Jianqi Ren +Signed-off-by: He Zhe +Signed-off-by: Greg Kroah-Hartman +--- + mm/mmap.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++---------------- + 1 file changed, 52 insertions(+), 17 deletions(-) + +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -2981,6 +2981,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsign + unsigned long populate = 0; + unsigned long ret = -EINVAL; + struct file *file; ++ vm_flags_t vm_flags; + + pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/mm/remap_file_pages.rst.\n", + current->comm, current->pid); +@@ -2997,12 +2998,60 @@ SYSCALL_DEFINE5(remap_file_pages, unsign + if (pgoff + (size >> PAGE_SHIFT) < pgoff) + return ret; + +- if (mmap_write_lock_killable(mm)) ++ if (mmap_read_lock_killable(mm)) + return -EINTR; + ++ /* ++ * Look up VMA under read lock first so we can perform the security ++ * without holding locks (which can be problematic). We reacquire a ++ * write lock later and check nothing changed underneath us. ++ */ + vma = vma_lookup(mm, start); + +- if (!vma || !(vma->vm_flags & VM_SHARED)) ++ if (!vma || !(vma->vm_flags & VM_SHARED)) { ++ mmap_read_unlock(mm); ++ return -EINVAL; ++ } ++ ++ prot |= vma->vm_flags & VM_READ ? PROT_READ : 0; ++ prot |= vma->vm_flags & VM_WRITE ? PROT_WRITE : 0; ++ prot |= vma->vm_flags & VM_EXEC ? PROT_EXEC : 0; ++ ++ flags &= MAP_NONBLOCK; ++ flags |= MAP_SHARED | MAP_FIXED | MAP_POPULATE; ++ if (vma->vm_flags & VM_LOCKED) ++ flags |= MAP_LOCKED; ++ ++ /* Save vm_flags used to calculate prot and flags, and recheck later. */ ++ vm_flags = vma->vm_flags; ++ file = get_file(vma->vm_file); ++ ++ mmap_read_unlock(mm); ++ ++ /* Call outside mmap_lock to be consistent with other callers. */ ++ ret = security_mmap_file(file, prot, flags); ++ if (ret) { ++ fput(file); ++ return ret; ++ } ++ ++ ret = -EINVAL; ++ ++ /* OK security check passed, take write lock + let it rip. */ ++ if (mmap_write_lock_killable(mm)) { ++ fput(file); ++ return -EINTR; ++ } ++ ++ vma = vma_lookup(mm, start); ++ ++ if (!vma) ++ goto out; ++ ++ /* Make sure things didn't change under us. */ ++ if (vma->vm_flags != vm_flags) ++ goto out; ++ if (vma->vm_file != file) + goto out; + + if (start + size > vma->vm_end) { +@@ -3030,25 +3079,11 @@ SYSCALL_DEFINE5(remap_file_pages, unsign + goto out; + } + +- prot |= vma->vm_flags & VM_READ ? PROT_READ : 0; +- prot |= vma->vm_flags & VM_WRITE ? PROT_WRITE : 0; +- prot |= vma->vm_flags & VM_EXEC ? PROT_EXEC : 0; +- +- flags &= MAP_NONBLOCK; +- flags |= MAP_SHARED | MAP_FIXED | MAP_POPULATE; +- if (vma->vm_flags & VM_LOCKED) +- flags |= MAP_LOCKED; +- +- file = get_file(vma->vm_file); +- ret = security_mmap_file(vma->vm_file, prot, flags); +- if (ret) +- goto out_fput; + ret = do_mmap(vma->vm_file, start, size, + prot, flags, 0, pgoff, &populate, NULL); +-out_fput: +- fput(file); + out: + mmap_write_unlock(mm); ++ fput(file); + if (populate) + mm_populate(ret, populate); + if (!IS_ERR_VALUE(ret)) diff --git a/queue-6.6/series b/queue-6.6/series index 93e3a8a3fb..19f795076c 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -141,3 +141,5 @@ qlcnic-fix-memory-leak-issues-in-qlcnic_sriov_common.c.patch smb-client-fix-regression-with-guest-option.patch rust-disallow-btf-generation-with-rust-lto.patch rust-init-fix-zeroable-implementation-for-option-nonnull-t-and-option-kbox-t.patch +lib-buildid-handle-memfd_secret-files-in-build_id_parse.patch +mm-split-critical-region-in-remap_file_pages-and-invoke-lsms-in-between.patch -- 2.47.3