Add comments to the map_count limit checks in do_mmap() and
do_brk_flags() to clarify their intended behavior.

The use of a strict inequality ('>') in these checks is intentional but
non-obvious. It allows these functions to succeed when the VMA count is
exactly at the sysctl_max_map_count limit. This historical behavior
accounts for cases where the operation might not create a new VMA, but
instead merge with or expand an existing one, in which case the VMA
count does not increase.

These comments clarify the long-standing behavior and will help prevent
future misinterpretation as an off-by-one error.

Signed-off-by: Kalesh Singh <[email protected]>
---

Changes in v4:
 - Keep the existing lenient behavior, per Hugh
 - Document this is intended, per Lorenzo

Changes in v3:
 - Collect Reviewed-by and Acked-by tags.

Changes in v2:
 - Fix mmap check, per Pedro

 mm/mmap.c | 9 +++++++++
 mm/vma.c  | 6 ++++++
 2 files changed, 15 insertions(+)

diff --git a/mm/mmap.c b/mm/mmap.c
index 644f02071a41..78843a2fae42 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -374,6 +374,15 @@ unsigned long do_mmap(struct file *file, unsigned long 
addr,
                return -EOVERFLOW;
 
        /* Too many mappings? */
+       /*
+        * The check is intentionally lenient (>) to allow an mmap() at the 
limit
+        * to succeed. This is for historical reasons, as the new mapping might
+        * merge with an adjacent VMA and not increase the total VMA count.
+        *
+        * If a merge does not occur, the process is allowed to exceed the
+        * sysctl_max_map_count limit by one. This behavior is preserved to
+        * avoid breaking existing applications.
+        */
        if (mm->map_count > sysctl_max_map_count)
                return -ENOMEM;
 
diff --git a/mm/vma.c b/mm/vma.c
index 919d1fc63a52..d0bb3127280e 100644
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -2813,6 +2813,12 @@ int do_brk_flags(struct vma_iterator *vmi, struct 
vm_area_struct *vma,
        if (!may_expand_vm(mm, vm_flags, len >> PAGE_SHIFT))
                return -ENOMEM;
 
+       /*
+        * The check is intentionally lenient (>) to allow brk() to succeed at
+        * the limit. This is for historical reasons, as expanding the heap
+        * typically extends the existing brk VMA rather than creating a new 
one.
+        * See also the comment in do_mmap().
+        */
        if (mm->map_count > sysctl_max_map_count)
                return -ENOMEM;
 
-- 
2.51.1.851.g4ebd6896fd-goog


Reply via email to