| From: Kalesh Singh <kaleshsingh@google.com> |
| Subject: mm: fix off-by-one error in VMA count limit checks |
| Date: Mon, 15 Sep 2025 09:36:32 -0700 |
| |
| The VMA count limit check in do_mmap() and do_brk_flags() uses a strict |
| inequality (>), which allows a process's VMA count to exceed the |
| configured sysctl_max_map_count limit by one. |
| |
| A process with mm->map_count == sysctl_max_map_count will incorrectly pass |
| this check and then exceed the limit upon allocation of a new VMA when its |
| map_count is incremented. |
| |
| Other VMA allocation paths, such as split_vma(), already use the correct, |
| inclusive (>=) comparison. |
| |
| Fix this bug by changing the comparison to be inclusive in do_mmap() and |
| do_brk_flags(), bringing them in line with the correct behavior of other |
| allocation paths. |
| |
| Link: https://lkml.kernel.org/r/20250915163838.631445-2-kaleshsingh@google.com |
| Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") |
| Signed-off-by: Kalesh Singh <kaleshsingh@google.com> |
| Cc: David Hildenbrand <david@redhat.com> |
| Cc: "Liam R. Howlett" <Liam.Howlett@oracle.com> |
| Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> |
| Cc: Mike Rapoport <rppt@kernel.org> |
| Cc: Minchan Kim <minchan@kernel.org> |
| Cc: Pedro Falcato <pfalcato@suse.de> |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| mm/mmap.c | 2 +- |
| mm/vma.c | 2 +- |
| 2 files changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/mm/mmap.c~mm-fix-off-by-one-error-in-vma-count-limit-checks |
| +++ a/mm/mmap.c |
| @@ -374,7 +374,7 @@ unsigned long do_mmap(struct file *file, |
| return -EOVERFLOW; |
| |
| /* Too many mappings? */ |
| - if (mm->map_count > sysctl_max_map_count) |
| + if (mm->map_count >= sysctl_max_map_count) |
| return -ENOMEM; |
| |
| /* |
| --- a/mm/vma.c~mm-fix-off-by-one-error-in-vma-count-limit-checks |
| +++ a/mm/vma.c |
| @@ -2772,7 +2772,7 @@ int do_brk_flags(struct vma_iterator *vm |
| if (!may_expand_vm(mm, vm_flags, len >> PAGE_SHIFT)) |
| return -ENOMEM; |
| |
| - if (mm->map_count > sysctl_max_map_count) |
| + if (mm->map_count >= sysctl_max_map_count) |
| return -ENOMEM; |
| |
| if (security_vm_enough_memory_mm(mm, len >> PAGE_SHIFT)) |
| _ |