Commit:     7cd94146cd504016315608e297219f9fb7b1413b
Parent:     8869477a49c3e99def1fcdadd6bbc407fea14b45
Author:     Eric Paris <[EMAIL PROTECTED]>
AuthorDate: Mon Nov 26 18:47:40 2007 -0500
Committer:  James Morris <[EMAIL PROTECTED]>
CommitDate: Thu Dec 6 00:25:10 2007 +1100

    Security: round mmap hint address above mmap_min_addr
    If mmap_min_addr is set and a process attempts to mmap (not fixed) with a
    non-null hint address less than mmap_min_addr the mapping will fail the
    security checks.  Since this is just a hint address this patch will round
    such a hint address above mmap_min_addr.
    gcj was found to try to be very frugal with vm usage and give hint addresses
    in the 8k-32k range.  Without this patch all such programs failed and with
    the patch they happily get a higher address.
    This patch is wrappad in CONFIG_SECURITY since mmap_min_addr doesn't exist
    without it and there would be no security check possible no matter what.  So
    we should not bother compiling in this rounding if it is just a waste of
    Signed-off-by: Eric Paris <[EMAIL PROTECTED]>
    Signed-off-by: James Morris <[EMAIL PROTECTED]>
 include/linux/mm.h |   16 ++++++++++++++++
 mm/mmap.c          |    3 +++
 mm/nommu.c         |    3 +++
 3 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 520238c..1b7b95c 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -12,6 +12,7 @@
 #include <linux/prio_tree.h>
 #include <linux/debug_locks.h>
 #include <linux/mm_types.h>
+#include <linux/security.h>
 struct mempolicy;
 struct anon_vma;
@@ -513,6 +514,21 @@ static inline void set_page_links(struct page *page, enum 
zone_type zone,
+ * If a hint addr is less than mmap_min_addr change hint to be as
+ * low as possible but still greater than mmap_min_addr
+ */
+static inline unsigned long round_hint_to_min(unsigned long hint)
+       hint &= PAGE_MASK;
+       if (((void *)hint != NULL) &&
+           (hint < mmap_min_addr))
+               return PAGE_ALIGN(mmap_min_addr);
+       return hint;
  * Some inline functions in vmstat.h depend on page_zone()
 #include <linux/vmstat.h>
diff --git a/mm/mmap.c b/mm/mmap.c
index 938313c..f4cfc6a 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -912,6 +912,9 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned 
long addr,
        if (!len)
                return -EINVAL;
+       if (!(flags & MAP_FIXED))
+               addr = round_hint_to_min(addr);
        error = arch_mmap_check(addr, len, flags);
        if (error)
                return error;
diff --git a/mm/nommu.c b/mm/nommu.c
index 35622c5..b989cb9 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -829,6 +829,9 @@ unsigned long do_mmap_pgoff(struct file *file,
        void *result;
        int ret;
+       if (!(flags & MAP_FIXED))
+               addr = round_hint_to_min(addr);
        /* decide whether we should attempt the mapping, and if so what sort of
         * mapping */
        ret = validate_mmap_request(file, addr, len, prot, flags, pgoff,
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at

Reply via email to