Skip to contentSkip to conversation

mmap: round mmap hint address above mmap_min_addr

PATCH In review Eric Paris 2 participants 4 messages Nov 16, 2007

Subsystems (3)
lore
Share & tools
lore

Eric Paris

author
#0 lore raw

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 both compiling in this rounding if it is just a waste of time.

---

 mm/mmap.c  |   10 ++++++++++
 mm/nommu.c |   10 ++++++++++
 2 files changed, 20 insertions(+), 0 deletions(-)
mm/mmap.c +10 -0
index 938313c..0c3ff74 100644
@@ -912,6 +912,16 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
 	if (!len)
 		return -EINVAL;
 
+#ifdef CONFIG_SECURITY
+	/*
+	 * If a hint addr is less than mmap_min_addr change addr to be as
+	 * low as possible but still greater than mmap_min_addr
+	 */
+	if (!(flags & MAP_FIXED) && ((void *)addr != NULL) &&
+	    (addr < mmap_min_addr))
+		addr = PAGE_ALIGN(mmap_min_addr);
+#endif
+
 	error = arch_mmap_check(addr, len, flags);
 	if (error)
 		return error;
mm/nommu.c +10 -0
index 35622c5..ea4d20a 100644
@@ -829,6 +829,16 @@ unsigned long do_mmap_pgoff(struct file *file,
 	void *result;
 	int ret;
 
+#ifdef CONFIG_SECURITY
+	/*
+	 * If a hint addr is less than mmap_min_addr change addr to be as
+	 * low as possible, but still greater than mmap_min_addr
+	 */
+	if (!(flags & MAP_FIXED) && ((void *)addr != NULL) &&
+	    (addr < mmap_min_addr))
+		addr = PAGE_ALIGN(mmap_min_addr);
+#endif
+
 	/* 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.

#1 lore raw

mm/mmap.c unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, · line 923

Quoted 9 lines · Eric Paris
mm/mmap.c +9 -0
+#ifdef CONFIG_SECURITY
+	/*
+	 * If a hint addr is less than mmap_min_addr change addr to be as
+	 * low as possible but still greater than mmap_min_addr
+	 */
+	if (!(flags & MAP_FIXED) && ((void *)addr != NULL) &&
+	    (addr < mmap_min_addr))
+		addr = PAGE_ALIGN(mmap_min_addr);
+#endif

Please make this a static inline which is optimized away with !CONFIG_SECURITY.

Quoted 27 lines
mm/mmap.c +1 -0
+
 	error = arch_mmap_check(addr, len, flags);
 	if (error)
 		return error;
mm/nommu.c +10 -0
index 35622c5..ea4d20a 100644
@@ -829,6 +829,16 @@ unsigned long do_mmap_pgoff(struct file *file,
 	void *result;
 	int ret;
 
+#ifdef CONFIG_SECURITY
+	/*
+	 * If a hint addr is less than mmap_min_addr change addr to be as
+	 * low as possible, but still greater than mmap_min_addr
+	 */
+	if (!(flags & MAP_FIXED) && ((void *)addr != NULL) &&
+	    (addr < mmap_min_addr))
+		addr = PAGE_ALIGN(mmap_min_addr);
+#endif
+
 	/* 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.
author
#2 lore raw
Quoted 14 lines · James Morris

mm/mmap.c unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, · line 923

Quoted 9 lines · Eric Paris
mm/mmap.c +9 -0
+#ifdef CONFIG_SECURITY
+	/*
+	 * If a hint addr is less than mmap_min_addr change addr to be as
+	 * low as possible but still greater than mmap_min_addr
+	 */
+	if (!(flags & MAP_FIXED) && ((void *)addr != NULL) &&
+	    (addr < mmap_min_addr))
+		addr = PAGE_ALIGN(mmap_min_addr);
+#endif

Please make this a static inline which is optimized away with !CONFIG_SECURITY.

Where do you think these should go? You think I should instead have a static inline function in both mmap.c and nommu.c so the CONFIG check isn't scattered in this code but still in this file? Or did you actually want something in security.h so I only have the code once?

-Eric

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

#3 lore raw
Quoted 16 lines · Eric Paris
Quoted 14 lines · James Morris

mm/mmap.c unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, · line 923

Quoted 9 lines · Eric Paris
mm/mmap.c +9 -0
+#ifdef CONFIG_SECURITY
+	/*
+	 * If a hint addr is less than mmap_min_addr change addr to be as
+	 * low as possible but still greater than mmap_min_addr
+	 */
+	if (!(flags & MAP_FIXED) && ((void *)addr != NULL) &&
+	    (addr < mmap_min_addr))
+		addr = PAGE_ALIGN(mmap_min_addr);
+#endif

Please make this a static inline which is optimized away with !CONFIG_SECURITY.

Quoted 4 lines

Where do you think these should go? You think I should instead have a static inline function in both mmap.c and nommu.c so the CONFIG check isn't scattered in this code but still in this file? Or did you actually want something in security.h so I only have the code once?

Both: not having #ifdefs in the core kernel code (we had pushback on this when LSM was being developed), and consolidating the code. It doesn't actually call into LSM modules, so may be better to put it in include/linux/mm.h.

- James

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.