linux-kernel November 2007 archive
Main Archive Page > Month Archives  > linux-kernel archives
linux-kernel: [PATCH 2/3 -v2] mmap: round mmap hint address abov

[PATCH 2/3 -v2] mmap: round mmap hint address above mmap_min_addr

From: Eric Paris <eparis_at_nospam>
Date: Mon Nov 26 2007 - 23:47:40 GMT

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 time.

Signed-off-by: Eric Paris <> --- 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) +{ +#ifdef CONFIG_SECURITY + hint &= PAGE_MASK; + if (((void *)hint != NULL) && + (hint < mmap_min_addr)) + return PAGE_ALIGN(mmap_min_addr); +#endif + 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, -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to with the words "unsubscribe selinux" without quotes as the message.