diff options
author | delphij <delphij@FreeBSD.org> | 2017-05-31 05:10:03 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2017-05-31 05:10:03 +0000 |
commit | bfde52da67b17e680ca5da34f553788ce1cbf7ef (patch) | |
tree | 4c8a0d1953b02c05a68b3ea408e34c0d4ca31aa5 /sys/vm | |
parent | 7ce24dc81f292794ddadd8289ff9cd494aa96852 (diff) | |
download | FreeBSD-src-bfde52da67b17e680ca5da34f553788ce1cbf7ef.zip FreeBSD-src-bfde52da67b17e680ca5da34f553788ce1cbf7ef.tar.gz |
MFC r315272, r315370
r315272:
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)
Differential Revision: https://reviews.freebsd.org/D427
r315370:
The adj_free and max_free values of new_entry will be calculated and
assigned by subsequent vm_map_entry_link(), therefore, remove the
pointless copying.
Submitted by: alc
Diffstat (limited to 'sys/vm')
-rw-r--r-- | sys/vm/vm.h | 1 | ||||
-rw-r--r-- | sys/vm/vm_map.c | 29 |
2 files changed, 30 insertions, 0 deletions
diff --git a/sys/vm/vm.h b/sys/vm/vm.h index 1df51fe..68bb4d1 100644 --- a/sys/vm/vm.h +++ b/sys/vm/vm.h @@ -68,6 +68,7 @@ typedef char vm_inherit_t; /* inheritance codes */ #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 */ diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 2296fb1..2ef89bd 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -2294,6 +2294,7 @@ vm_map_inherit(vm_map_t map, vm_offset_t start, vm_offset_t end, case VM_INHERIT_NONE: case VM_INHERIT_COPY: case VM_INHERIT_SHARE: + case VM_INHERIT_ZERO: break; default: return (KERN_INVALID_ARGUMENT); @@ -3452,6 +3453,34 @@ vmspace_fork(struct vmspace *vm1, vm_ooffset_t *fork_charge) 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->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; } |