svn commit: r271635 - in head: lib/libc/sys sys/vm

Andriy Gapon avg at FreeBSD.org
Tue Sep 16 13:39:24 UTC 2014


On 15/09/2014 20:20, John Baldwin wrote:
> Author: jhb
> Date: Mon Sep 15 17:20:13 2014
> New Revision: 271635
> URL: http://svnweb.freebsd.org/changeset/base/271635
> 
> Log:
>   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.

This broke Java, at least java/openjdk7, for me:

 25323 java     CALL
mmap(0,0x3000000,0x3<PROT_READ|PROT_WRITE>,0x1042<MAP_PRIVATE|MAP_NORESERVE|MAP_ANON>,0xffffffff,0)
 25323 java     RET   mmap -1 errno 22 Invalid argument
 25323 java     CALL  write(0x1,0x7fffffbfd450,0x2b)
 25323 java     GIO   fd 1 wrote 43 bytes
       "Error occurred during initialization of VM
       "
 25323 java     RET   write 43/0x2b
 25323 java     CALL  write(0x1,0x80209a1e2,0x2d)
 25323 java     GIO   fd 1 wrote 45 bytes
       "Could not reserve enough space for code cache"

It seems that MAP_NORESERVE presence could be detected in sys/mman.h and then it
is used for some reason.
I guess that the port can be easily fixed, but this commit breaks compatibility
with older binaries.  Perhaps MAP_NORESERVE should be removed as well given that
we do not actually implement it.

>   Reviewed by:	alc, kib
>   MFC after:	2 weeks
>   Differential Revision:	https://reviews.freebsd.org/D698
> 
> Modified:
>   head/lib/libc/sys/mmap.2
>   head/sys/vm/vm_mmap.c
> 
> Modified: head/lib/libc/sys/mmap.2
> ==============================================================================
> --- head/lib/libc/sys/mmap.2	Mon Sep 15 17:14:09 2014	(r271634)
> +++ head/lib/libc/sys/mmap.2	Mon Sep 15 17:20:13 2014	(r271635)
> @@ -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
> 
> Modified: head/sys/vm/vm_mmap.c
> ==============================================================================
> --- head/sys/vm/vm_mmap.c	Mon Sep 15 17:14:09 2014	(r271634)
> +++ head/sys/vm/vm_mmap.c	Mon Sep 15 17:20:13 2014	(r271635)
> @@ -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;
> 


-- 
Andriy Gapon


More information about the svn-src-head mailing list