Add stricter checking of some mmap() arguments:
- Fail with EINVAL if an invalid protection mask is passed to mmap(). - Fail with EINVAL if an unknown flag is passed to mmap(). - Fail with EINVAL if both MAP_PRIVATE and MAP_SHARED are passed to mmap(). - Require one of either MAP_PRIVATE or MAP_SHARED for non-anonymous mappings. Reviewed by: alc, kib MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D698
This commit is contained in:
parent
a7fecb4d3a
commit
5fd3f8b3b6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=271635
@ -28,7 +28,7 @@
|
||||
.\" @(#)mmap.2 8.4 (Berkeley) 5/11/95
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 19, 2014
|
||||
.Dd September 15, 2014
|
||||
.Dt MMAP 2
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -372,6 +372,29 @@ The
|
||||
argument
|
||||
is not a valid open file descriptor.
|
||||
.It Bq Er EINVAL
|
||||
An invalid value was passed in the
|
||||
.Fa prot
|
||||
argument.
|
||||
.It Bq Er EINVAL
|
||||
An undefined option was set in the
|
||||
.Fa flags
|
||||
argument.
|
||||
.It Bq Er EINVAL
|
||||
Both
|
||||
.Dv MAP_PRIVATE
|
||||
and
|
||||
.Dv MAP_SHARED
|
||||
were specified.
|
||||
.It Bq Er EINVAL
|
||||
None of
|
||||
.Dv MAP_ANON ,
|
||||
.Dv MAP_PRIVATE ,
|
||||
.Dv MAP_SHARED ,
|
||||
or
|
||||
.Dv MAP_STACK
|
||||
was specified.
|
||||
At least one of these flags must be included.
|
||||
.It Bq Er EINVAL
|
||||
.Dv MAP_FIXED
|
||||
was specified and the
|
||||
.Fa addr
|
||||
|
@ -203,17 +203,17 @@ sys_mmap(td, uap)
|
||||
struct vnode *vp;
|
||||
vm_offset_t addr;
|
||||
vm_size_t size, pageoff;
|
||||
vm_prot_t cap_maxprot, prot, maxprot;
|
||||
vm_prot_t cap_maxprot, maxprot;
|
||||
void *handle;
|
||||
objtype_t handle_type;
|
||||
int align, error, flags;
|
||||
int align, error, flags, prot;
|
||||
off_t pos;
|
||||
struct vmspace *vms = td->td_proc->p_vmspace;
|
||||
cap_rights_t rights;
|
||||
|
||||
addr = (vm_offset_t) uap->addr;
|
||||
size = uap->len;
|
||||
prot = uap->prot & VM_PROT_ALL;
|
||||
prot = uap->prot;
|
||||
flags = uap->flags;
|
||||
pos = uap->pos;
|
||||
|
||||
@ -244,8 +244,23 @@ sys_mmap(td, uap)
|
||||
flags |= MAP_ANON;
|
||||
pos = 0;
|
||||
}
|
||||
/* XXX: MAP_RENAME, MAP_NORESERVE */
|
||||
if ((flags & ~(MAP_SHARED | MAP_PRIVATE | MAP_FIXED | MAP_HASSEMAPHORE |
|
||||
MAP_STACK | MAP_NOSYNC | MAP_ANON | MAP_EXCL | MAP_NOCORE |
|
||||
MAP_PREFAULT_READ |
|
||||
#ifdef MAP_32BIT
|
||||
MAP_32BIT |
|
||||
#endif
|
||||
MAP_ALIGNMENT_MASK)) != 0)
|
||||
return (EINVAL);
|
||||
if ((flags & (MAP_EXCL | MAP_FIXED)) == MAP_EXCL)
|
||||
return (EINVAL);
|
||||
if ((flags & (MAP_ANON | MAP_SHARED | MAP_PRIVATE)) == 0 ||
|
||||
(flags & (MAP_SHARED | MAP_PRIVATE)) == (MAP_SHARED | MAP_PRIVATE))
|
||||
return (EINVAL);
|
||||
if (prot != PROT_NONE &&
|
||||
(prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) != 0)
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
* Align the file position to a page boundary,
|
||||
@ -415,6 +430,8 @@ sys_mmap(td, uap)
|
||||
map:
|
||||
td->td_fpop = fp;
|
||||
maxprot &= cap_maxprot;
|
||||
|
||||
/* This relies on VM_PROT_* matching PROT_*. */
|
||||
error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot,
|
||||
flags, handle_type, handle, pos);
|
||||
td->td_fpop = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user