Add MAP_EXCL flag for mmap(2). It should be combined with MAP_FIXED,

and prevents the request from deleting existing mappings in the
region, failing instead.

Reviewed by:	alc
Discussed with:	jhb
Tested by:	markj, pho (previous version, as part of the bigger patch)
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2014-06-19 05:00:39 +00:00
parent 8efb419829
commit 11c42bcc54
5 changed files with 35 additions and 7 deletions

View File

@ -28,7 +28,7 @@
.\" @(#)mmap.2 8.4 (Berkeley) 5/11/95
.\" $FreeBSD$
.\"
.Dd September 9, 2013
.Dd June 19, 2014
.Dt MMAP 2
.Os
.Sh NAME
@ -141,6 +141,12 @@ argument must be 0.
This flag is identical to
.Dv MAP_ANON
and is provided for compatibility.
.It Dv MAP_EXCL
This flag can only be used in combination with
.Dv MAP_FIXED .
Please see the definition of
.Dv MAP_FIXED
for the description of its effect.
.It Dv MAP_FIXED
Do not permit the system to select a different address than the one
specified.
@ -152,17 +158,21 @@ If
is specified,
.Fa addr
must be a multiple of the pagesize.
If a
If
.Dv MAP_EXCL
is not specified, a successfull
.Dv MAP_FIXED
request is successful, the mapping established by
.Fn mmap
replaces any previous mappings for the process' pages in the range from
request replaces any previous mappings for the process'
pages in the range from
.Fa addr
to
.Fa addr
+
.Fa len .
Use of this option is discouraged.
In contrast, if
.Dv MAP_EXCL
is specified, the request will fail if a mapping
already exists within the range.
.It Dv MAP_HASSEMAPHORE
Notify the kernel that the region may contain semaphores and that special
handling may be necessary.
@ -393,6 +403,17 @@ argument was not -1.
was specified and the
.Fa offset
argument was not 0.
.It Bq Er EINVAL
Both
.Dv MAP_FIXED
and
.Dv MAP_EXCL
were specified, but the requested region is already used by a mapping.
.It Bq Er EINVAL
.Dv MAP_EXCL
was specified, but
.Dv MAP_FIXED
was not.
.It Bq Er ENODEV
.Dv MAP_ANON
has not been specified and

View File

@ -89,6 +89,7 @@
/*
* Extended flags
*/
#define MAP_EXCL 0x00004000 /* for MAP_FIXED, fail if address is used */
#define MAP_NOCORE 0x00020000 /* dont include these pages in a coredump */
#define MAP_PREFAULT_READ 0x00040000 /* prefault mapping for reading */
#ifdef __LP64__

View File

@ -1393,7 +1393,8 @@ vm_map_fixed(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
("vm_map_fixed: non-NULL backing object for stack"));
vm_map_lock(map);
VM_MAP_RANGE_CHECK(map, start, end);
(void) vm_map_delete(map, start, end);
if ((cow & MAP_CHECK_EXCL) == 0)
vm_map_delete(map, start, end);
if ((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) != 0) {
result = vm_map_stack_locked(map, start, length, sgrowsiz,
prot, max, cow);

View File

@ -315,6 +315,7 @@ long vmspace_resident_count(struct vmspace *vmspace);
#define MAP_PREFAULT 0x0008
#define MAP_PREFAULT_PARTIAL 0x0010
#define MAP_DISABLE_SYNCER 0x0020
#define MAP_CHECK_EXCL 0x0040
#define MAP_DISABLE_COREDUMP 0x0100
#define MAP_PREFAULT_MADVISE 0x0200 /* from (user) madvise request */
#define MAP_VN_WRITECOUNT 0x0400

View File

@ -245,6 +245,8 @@ sys_mmap(td, uap)
flags |= MAP_ANON;
pos = 0;
}
if ((flags & (MAP_EXCL | MAP_FIXED)) == MAP_EXCL)
return (EINVAL);
/*
* Align the file position to a page boundary,
@ -1626,6 +1628,8 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
return (EINVAL);
docow |= MAP_STACK_GROWS_DOWN;
}
if ((flags & MAP_EXCL) != 0)
docow |= MAP_CHECK_EXCL;
if (fitit) {
if ((flags & MAP_ALIGNMENT_MASK) == MAP_ALIGNED_SUPER)