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

Alan Cox alc at rice.edu
Wed Mar 15 13:06:47 UTC 2017


On 03/14/2017 12:10, Xin LI wrote:
> Author: delphij
> Date: Tue Mar 14 17:10:42 2017
> New Revision: 315272
> URL: https://svnweb.freebsd.org/changeset/base/315272
>
> Log:
>   Implement INHERIT_ZERO for minherit(2).
>   
>   INHERIT_ZERO is an OpenBSD feature.
>   
>   When a page is marked as such, it would be zeroed
>   upon fork().
>   
>   This would be used in new arc4random(3) functions.
>   
>   PR:	182610
>   Reviewed by:	kib (earlier version)
>   MFC after:	1 month
>   Differential Revision:	https://reviews.freebsd.org/D427
>
> Modified:
>   head/lib/libc/sys/minherit.2
>   head/sys/sys/mman.h
>   head/sys/vm/vm.h
>   head/sys/vm/vm_map.c
>
> Modified: head/lib/libc/sys/minherit.2
> ==============================================================================
> --- head/lib/libc/sys/minherit.2	Tue Mar 14 16:40:18 2017	(r315271)
> +++ head/lib/libc/sys/minherit.2	Tue Mar 14 17:10:42 2017	(r315272)
> @@ -29,7 +29,7 @@
>  .\"
>  .\"	@(#)minherit.2	8.1 (Berkeley) 6/9/93
>  .\"
> -.Dd October 30, 2007
> +.Dd March 15, 2017
>  .Dt MINHERIT 2
>  .Os
>  .Sh NAME
> @@ -91,6 +91,11 @@ it will no longer be shared in the paren
>  after the parent forks and there is no way to get the previous
>  shared-backing-store mapping without unmapping and remapping the address
>  space in the parent.
> +.It Dv INHERIT_ZERO
> +This option causes the address space in question to be mapped as new
> +anonymous pages,
> +which would be initialized to all zero bytes,
> +in the child process.
>  .El
>  .Sh RETURN VALUES
>  .Rv -std minherit
> @@ -130,6 +135,13 @@ system call first appeared in
>  .Ox
>  and then in
>  .Fx 2.2 .
> +.Pp
> +The
> +.Dv INHERIT_ZERO
> +support first appeared in
> +.Ox 5.6
> +and then in
> +.Fx 12.0 .
>  .Sh BUGS
>  Once you set inheritance to
>  .Dv MAP_PRIVATE
>
> Modified: head/sys/sys/mman.h
> ==============================================================================
> --- head/sys/sys/mman.h	Tue Mar 14 16:40:18 2017	(r315271)
> +++ head/sys/sys/mman.h	Tue Mar 14 17:10:42 2017	(r315272)
> @@ -43,6 +43,7 @@
>  #define INHERIT_SHARE	0
>  #define INHERIT_COPY	1
>  #define INHERIT_NONE	2
> +#define INHERIT_ZERO	3
>  #endif
>  
>  /*
>
> Modified: head/sys/vm/vm.h
> ==============================================================================
> --- head/sys/vm/vm.h	Tue Mar 14 16:40:18 2017	(r315271)
> +++ head/sys/vm/vm.h	Tue Mar 14 17:10:42 2017	(r315272)
> @@ -68,6 +68,7 @@ typedef char vm_inherit_t;	/* inheritanc
>  #define	VM_INHERIT_SHARE	((vm_inherit_t) 0)
>  #define	VM_INHERIT_COPY		((vm_inherit_t) 1)
>  #define	VM_INHERIT_NONE		((vm_inherit_t) 2)
> +#define	VM_INHERIT_ZERO		((vm_inherit_t) 3)
>  #define	VM_INHERIT_DEFAULT	VM_INHERIT_COPY
>  
>  typedef u_char vm_prot_t;	/* protection codes */
>
> Modified: head/sys/vm/vm_map.c
> ==============================================================================
> --- head/sys/vm/vm_map.c	Tue Mar 14 16:40:18 2017	(r315271)
> +++ head/sys/vm/vm_map.c	Tue Mar 14 17:10:42 2017	(r315272)
> @@ -2285,6 +2285,7 @@ vm_map_inherit(vm_map_t map, vm_offset_t
>  	case VM_INHERIT_NONE:
>  	case VM_INHERIT_COPY:
>  	case VM_INHERIT_SHARE:
> +	case VM_INHERIT_ZERO:
>  		break;
>  	default:
>  		return (KERN_INVALID_ARGUMENT);
> @@ -3443,6 +3444,36 @@ vmspace_fork(struct vmspace *vm1, vm_oof
>  			vm_map_copy_entry(old_map, new_map, old_entry,
>  			    new_entry, fork_charge);
>  			break;
> +
> +		case VM_INHERIT_ZERO:
> +			/*
> +			 * Create a new anonymous mapping entry modelled from
> +			 * the old one.
> +			 */
> +			new_entry = vm_map_entry_create(new_map);
> +			memset(new_entry, 0, sizeof(*new_entry));
> +
> +			new_entry->start = old_entry->start;
> +			new_entry->end = old_entry->end;
> +			new_entry->avail_ssize = old_entry->avail_ssize;
> +			new_entry->adj_free = old_entry->adj_free;
> +			new_entry->max_free = old_entry->max_free;

The previous two fields should not be copied.  The values from the old
entry are not necessarily correct for the new entry.  The correct values
are calculated and assigned by the call to vm_map_entry_link() below. 
So, these two assignments are harmless but also pointless.

> +			new_entry->eflags = old_entry->eflags &
> +			    ~(MAP_ENTRY_USER_WIRED | MAP_ENTRY_IN_TRANSITION |
> +			    MAP_ENTRY_VN_WRITECNT);
> +			new_entry->protection = old_entry->protection;
> +			new_entry->max_protection = old_entry->max_protection;
> +			new_entry->inheritance = VM_INHERIT_ZERO;
> +
> +			vm_map_entry_link(new_map, new_map->header.prev,
> +			    new_entry);
> +			vmspace_map_entry_forked(vm1, vm2, new_entry);
> +
> +			new_entry->cred = curthread->td_ucred;
> +			crhold(new_entry->cred);
> +			*fork_charge += (new_entry->end - new_entry->start);
> +
> +			break;
>  		}
>  		old_entry = old_entry->next;
>  	}
>
>




More information about the svn-src-all mailing list