]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.5-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Nov 2023 11:34:30 +0000 (12:34 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Nov 2023 11:34:30 +0000 (12:34 +0100)
added patches:
mmap-fix-error-paths-with-dup_anon_vma.patch
mmap-fix-vma_iterator-in-error-path-of-vma_merge.patch

queue-6.5/mmap-fix-error-paths-with-dup_anon_vma.patch [new file with mode: 0644]
queue-6.5/mmap-fix-vma_iterator-in-error-path-of-vma_merge.patch [new file with mode: 0644]
queue-6.5/series

diff --git a/queue-6.5/mmap-fix-error-paths-with-dup_anon_vma.patch b/queue-6.5/mmap-fix-error-paths-with-dup_anon_vma.patch
new file mode 100644 (file)
index 0000000..c54132e
--- /dev/null
@@ -0,0 +1,150 @@
+From 824135c46b00df7fb369ec7f1f8607427bbebeb0 Mon Sep 17 00:00:00 2001
+From: "Liam R. Howlett" <Liam.Howlett@oracle.com>
+Date: Fri, 29 Sep 2023 14:30:40 -0400
+Subject: mmap: fix error paths with dup_anon_vma()
+
+From: Liam R. Howlett <Liam.Howlett@oracle.com>
+
+commit 824135c46b00df7fb369ec7f1f8607427bbebeb0 upstream.
+
+When the calling function fails after the dup_anon_vma(), the
+duplication of the anon_vma is not being undone.  Add the necessary
+unlink_anon_vma() call to the error paths that are missing them.
+
+This issue showed up during inspection of the error path in vma_merge()
+for an unrelated vma iterator issue.
+
+Users may experience increased memory usage, which may be problematic as
+the failure would likely be caused by a low memory situation.
+
+Link: https://lkml.kernel.org/r/20230929183041.2835469-3-Liam.Howlett@oracle.com
+Fixes: d4af56c5c7c6 ("mm: start tracking VMAs with maple tree")
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Reviewed-by: Lorenzo Stoakes <lstoakes@gmail.com>
+Acked-by: Vlastimil Babka <vbabka@suse.cz>
+Cc: Jann Horn <jannh@google.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/mmap.c |   30 ++++++++++++++++++++++--------
+ 1 file changed, 22 insertions(+), 8 deletions(-)
+
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -603,11 +603,12 @@ again:
+  * dup_anon_vma() - Helper function to duplicate anon_vma
+  * @dst: The destination VMA
+  * @src: The source VMA
++ * @dup: Pointer to the destination VMA when successful.
+  *
+  * Returns: 0 on success.
+  */
+ static inline int dup_anon_vma(struct vm_area_struct *dst,
+-                             struct vm_area_struct *src)
++              struct vm_area_struct *src, struct vm_area_struct **dup)
+ {
+       /*
+        * Easily overlooked: when mprotect shifts the boundary, make sure the
+@@ -615,9 +616,15 @@ static inline int dup_anon_vma(struct vm
+        * anon pages imported.
+        */
+       if (src->anon_vma && !dst->anon_vma) {
++              int ret;
++
+               vma_start_write(dst);
+               dst->anon_vma = src->anon_vma;
+-              return anon_vma_clone(dst, src);
++              ret = anon_vma_clone(dst, src);
++              if (ret)
++                      return ret;
++
++              *dup = dst;
+       }
+       return 0;
+@@ -644,6 +651,7 @@ int vma_expand(struct vma_iterator *vmi,
+              unsigned long start, unsigned long end, pgoff_t pgoff,
+              struct vm_area_struct *next)
+ {
++      struct vm_area_struct *anon_dup = NULL;
+       bool remove_next = false;
+       struct vma_prepare vp;
+@@ -651,7 +659,7 @@ int vma_expand(struct vma_iterator *vmi,
+               int ret;
+               remove_next = true;
+-              ret = dup_anon_vma(vma, next);
++              ret = dup_anon_vma(vma, next, &anon_dup);
+               if (ret)
+                       return ret;
+       }
+@@ -683,6 +691,8 @@ int vma_expand(struct vma_iterator *vmi,
+       return 0;
+ nomem:
++      if (anon_dup)
++              unlink_anon_vmas(anon_dup);
+       return -ENOMEM;
+ }
+@@ -881,6 +891,7 @@ struct vm_area_struct *vma_merge(struct
+ {
+       struct vm_area_struct *curr, *next, *res;
+       struct vm_area_struct *vma, *adjust, *remove, *remove2;
++      struct vm_area_struct *anon_dup = NULL;
+       struct vma_prepare vp;
+       pgoff_t vma_pgoff;
+       int err = 0;
+@@ -945,16 +956,16 @@ struct vm_area_struct *vma_merge(struct
+           is_mergeable_anon_vma(prev->anon_vma, next->anon_vma, NULL)) {
+               remove = next;                          /* case 1 */
+               vma_end = next->vm_end;
+-              err = dup_anon_vma(prev, next);
++              err = dup_anon_vma(prev, next, &anon_dup);
+               if (curr) {                             /* case 6 */
+                       remove = curr;
+                       remove2 = next;
+                       if (!next->anon_vma)
+-                              err = dup_anon_vma(prev, curr);
++                              err = dup_anon_vma(prev, curr, &anon_dup);
+               }
+       } else if (merge_prev) {                        /* case 2 */
+               if (curr) {
+-                      err = dup_anon_vma(prev, curr);
++                      err = dup_anon_vma(prev, curr, &anon_dup);
+                       if (end == curr->vm_end) {      /* case 7 */
+                               remove = curr;
+                       } else {                        /* case 5 */
+@@ -968,7 +979,7 @@ struct vm_area_struct *vma_merge(struct
+                       vma_end = addr;
+                       adjust = next;
+                       adj_start = -(prev->vm_end - addr);
+-                      err = dup_anon_vma(next, prev);
++                      err = dup_anon_vma(next, prev, &anon_dup);
+               } else {
+                       /*
+                        * Note that cases 3 and 8 are the ONLY ones where prev
+@@ -981,7 +992,7 @@ struct vm_area_struct *vma_merge(struct
+                       if (curr) {                     /* case 8 */
+                               vma_pgoff = curr->vm_pgoff;
+                               remove = curr;
+-                              err = dup_anon_vma(next, curr);
++                              err = dup_anon_vma(next, curr, &anon_dup);
+                       }
+               }
+       }
+@@ -1026,6 +1037,9 @@ struct vm_area_struct *vma_merge(struct
+       return res;
+ prealloc_fail:
++      if (anon_dup)
++              unlink_anon_vmas(anon_dup);
++
+ anon_vma_fail:
+       vma_iter_set(vmi, addr);
+       vma_iter_load(vmi);
diff --git a/queue-6.5/mmap-fix-vma_iterator-in-error-path-of-vma_merge.patch b/queue-6.5/mmap-fix-vma_iterator-in-error-path-of-vma_merge.patch
new file mode 100644 (file)
index 0000000..e705fa9
--- /dev/null
@@ -0,0 +1,62 @@
+From 1419430c8abb5a00590169068590dd54d86590ba Mon Sep 17 00:00:00 2001
+From: "Liam R. Howlett" <Liam.Howlett@oracle.com>
+Date: Fri, 29 Sep 2023 14:30:39 -0400
+Subject: mmap: fix vma_iterator in error path of vma_merge()
+
+From: Liam R. Howlett <Liam.Howlett@oracle.com>
+
+commit 1419430c8abb5a00590169068590dd54d86590ba upstream.
+
+During the error path, the vma iterator may not be correctly positioned or
+set to the correct range.  Undo the vma_prev() call by resetting to the
+passed in address.  Re-walking to the same range will fix the range to the
+area previously passed in.
+
+Users would notice increased cycles as vma_merge() would be called an
+extra time with vma == prev, and thus would fail to merge and return.
+
+Link: https://lore.kernel.org/linux-mm/CAG48ez12VN1JAOtTNMY+Y2YnsU45yL5giS-Qn=ejtiHpgJAbdQ@mail.gmail.com/
+Link: https://lkml.kernel.org/r/20230929183041.2835469-2-Liam.Howlett@oracle.com
+Fixes: 18b098af2890 ("vma_merge: set vma iterator to correct position.")
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Reported-by: Jann Horn <jannh@google.com>
+Closes: https://lore.kernel.org/linux-mm/CAG48ez12VN1JAOtTNMY+Y2YnsU45yL5giS-Qn=ejtiHpgJAbdQ@mail.gmail.com/
+Reviewed-by: Lorenzo Stoakes <lstoakes@gmail.com>
+Acked-by: Vlastimil Babka <vbabka@suse.cz>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/mmap.c |   10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -988,10 +988,10 @@ struct vm_area_struct *vma_merge(struct
+       /* Error in anon_vma clone. */
+       if (err)
+-              return NULL;
++              goto anon_vma_fail;
+       if (vma_iter_prealloc(vmi))
+-              return NULL;
++              goto prealloc_fail;
+       init_multi_vma_prep(&vp, vma, adjust, remove, remove2);
+       VM_WARN_ON(vp.anon_vma && adjust && adjust->anon_vma &&
+@@ -1024,6 +1024,12 @@ struct vm_area_struct *vma_merge(struct
+       khugepaged_enter_vma(res, vm_flags);
+       return res;
++
++prealloc_fail:
++anon_vma_fail:
++      vma_iter_set(vmi, addr);
++      vma_iter_load(vmi);
++      return NULL;
+ }
+ /*
index fbfe0a81057b002ac9525823566b61d9088ca1ed..022c0f094aaa5d5eef6fd7ca13c84f000a632986 100644 (file)
@@ -63,3 +63,5 @@ rust-make-unsafecell-the-outer-type-in-opaque.patch
 rust-types-make-opaque-be-unpin.patch
 power-supply-core-use-blocking_notifier_call_chain-t.patch
 perf-evlist-avoid-frequency-mode-for-the-dummy-event.patch
+mmap-fix-vma_iterator-in-error-path-of-vma_merge.patch
+mmap-fix-error-paths-with-dup_anon_vma.patch