mmap: round mmap hint address above mmap_min_addr
Subsystems (4)
PATCH 2/3 mmap: 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 time.
---
include/linux/mm.h | 16 ++++++++++++++++ mm/mmap.c | 3 +++ mm/nommu.c | 3 +++ 3 files changed, 22 insertions(+), 0 deletions(-)
include/linux/mm.h +16 -0
@@ -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>
mm/mmap.c +3 -0
@@ -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;
mm/nommu.c +3 -0
@@ -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 [email protected] with the words "unsubscribe selinux" without quotes as the message.
Quoted 9 lines · Eric Paris
If
mmap_min_addris set and a process attempts to mmap (not fixed) with a non-null hint address less thanmmap_min_addrthe mapping will fail the security checks. Since this is just a hint address this patch will round such a hint address abovemmap_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.
Quoted 6 lines
This patch is wrappad in
CONFIG_SECURITYsincemmap_min_addrdoesn'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 <[email protected]>
Applied togit://git.kernel.org/pub/scm/linux/kernel/git/jmorris/selinux-2.6.git#for-akpm
Quoted 72 lines
---
include/linux/mm.h | 16 ++++++++++++++++ mm/mmap.c | 3 +++ mm/nommu.c | 3 +++ 3 files changed, 22 insertions(+), 0 deletions(-)include/linux/mm.h +16
-0@@ -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> mm/mmap.c +3
-0@@ -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;mm/nommu.c +3
-0@@ -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,
Signature · 7 lines
James Morris <[email protected]> -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.