kern/71258: [patch] anonymous mmappings not always page aligned

dada at sbox.tugraz.at dada at sbox.tugraz.at
Wed Sep 1 10:50:26 PDT 2004


>Number:         71258
>Category:       kern
>Synopsis:       [patch] anonymous mmappings not always page aligned
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Sep 01 17:50:26 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Martin Kammerhofer
>Release:        FreeBSD 4.10-RELEASE-p2 i386
>Organization:
Graz Uni
>Environment:
System: FreeBSD Martin.liebt.Susi 4.10-RELEASE-p2 FreeBSD 4.10-RELEASE-p2 #3: Mon Aug 30 22:43:58 CEST 2004 toor at Martin.liebt.Susi:/mnt/redhat/freebsd/usr/src/sys/compile/GEIDORF4 i386
>Description:
Quote from the mmap(2) manpage:

     MAP_ANON          Map anonymous memory not associated with any specific
		       file.  The file descriptor used for creating MAP_ANON
		       must be -1.  The offset argument is ignored.
		                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The actual implementation _does_ use the offset argument. The offset
modulo the hardware page size is used for size calculation and added
to the return value.

(This should be no problem with POSIX conforming applications because
POSIX _mandates_ EINVAL for nonaligned offsets.)
>How-To-Repeat:
#include <sys/types.h>
#include <sys/mman.h>
#include <stdio.h>

main() {
    printf("%p\n", mmap(0, 0x1000, PROT_NONE, MAP_ANON, -1, 0x12345678));
}
>Fix:
--- vm_mmap.c.orig	Thu Aug  5 09:04:33 2004
+++ vm_mmap.c	Tue Aug 31 12:47:11 2004
@@ -227,25 +227,28 @@
 
 	if (flags & MAP_STACK) {
 		if ((uap->fd != -1) ||
 		    ((prot & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE)))
 			return (EINVAL);
 		flags |= MAP_ANON;
-		pos = 0;
 	}
 
-	/*
-	 * Align the file position to a page boundary,
-	 * and save its page offset component.
-	 */
-	pageoff = (pos & PAGE_MASK);
-	pos -= pageoff;
+	if (flags & MAP_ANON) {
+		pageoff = pos = 0;
+	} else {
+		/*
+		 * Align the file position to a page boundary,
+		 * and save its page offset component.
+		 */
+		pageoff = (pos & PAGE_MASK);
+		pos -= pageoff;
 
-	/* Adjust size for rounding (on both ends). */
-	size += pageoff;			/* low end... */
-	size = (vm_size_t) round_page(size);	/* hi end */
+		/* Adjust size for rounding (on both ends). */
+		size += pageoff;			/* low end... */
+		size = (vm_size_t) round_page(size);	/* hi end */
+	}
 
 	/*
 	 * Check for illegal addresses.  Watch out for address wrap... Note
 	 * that VM_*_ADDRESS are not constants due to casts (argh).
 	 */
 	if (flags & MAP_FIXED) {
@@ -284,13 +287,12 @@
 	if (flags & MAP_ANON) {
 		/*
 		 * Mapping blank space is trivial.
 		 */
 		handle = NULL;
 		maxprot = VM_PROT_ALL;
-		pos = 0;
 	} else {
 		/*
 		 * Mapping file, get fp for validation. Obtain vnode and make
 		 * sure it is of appropriate type.
 		 * don't let the descriptor disappear on us if we block
 		 */

--=_3r61v0pks0u8--

>Release-Note:
>Audit-Trail:
>Unformatted:
 This message is in MIME format.
 
 --=_3r61v0pks0u8
 Content-Type: text/plain; charset=ISO-8859-1
 Content-Disposition: inline
 Content-Transfer-Encoding: 7bit
 
 
 --=_3r61v0pks0u8
 Content-Type: text/plain; charset=UTF-8; name="mmap.pr"
 Content-Disposition: inline; filename="mmap.pr"
 Content-Transfer-Encoding: 7bit
 


More information about the freebsd-bugs mailing list