diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-09-04 16:15:31 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-09-04 16:15:31 +0000 |
commit | 240b0df14655a608cf18947b63f783a1903510d9 (patch) | |
tree | 1eb21f08cb4199c5d40cd1f572a2f49b77258032 /sys | |
parent | 9d92c579ae5a08ed275dd1d92ce7a553af5769ab (diff) |
Rototil the _rs_clearseed() function once more such that we don't map pages
beyond the end of .text/.rodata.
ok deraadt@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/rnd.c | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/sys/dev/rnd.c b/sys/dev/rnd.c index f18c9c5ae65..affc45886a2 100644 --- a/sys/dev/rnd.c +++ b/sys/dev/rnd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rnd.c,v 1.184 2016/09/03 11:40:54 kettenis Exp $ */ +/* $OpenBSD: rnd.c,v 1.185 2016/09/04 16:15:30 kettenis Exp $ */ /* * Copyright (c) 2011 Theo de Raadt. @@ -617,32 +617,34 @@ _rs_clearseed(const void *p, size_t s) struct kmem_dyn_mode kd_avoidalias; vaddr_t va = trunc_page((vaddr_t)p); vsize_t off = (vaddr_t)p - va; + vsize_t len; vaddr_t rwva; - paddr_t pa[3]; - int i; + paddr_t pa; - KASSERT(s <= (nitems(pa) - 1) * PAGE_SIZE); + while (s > 0) { + pmap_extract(pmap_kernel(), va, &pa); - for (i = 0; i < nitems(pa); i++, va += PAGE_SIZE) - pmap_extract(pmap_kernel(), va, &pa[i]); + memset(&kd_avoidalias, 0, sizeof kd_avoidalias); + kd_avoidalias.kd_prefer = pa; + kd_avoidalias.kd_waitok = 1; + rwva = (vaddr_t)km_alloc(PAGE_SIZE, &kv_any, &kp_none, + &kd_avoidalias); + if (!rwva) + panic("_rs_clearseed"); - memset(&kd_avoidalias, 0, sizeof kd_avoidalias); - kd_avoidalias.kd_prefer = pa[0]; - kd_avoidalias.kd_waitok = 1; - rwva = (vaddr_t)km_alloc(nitems(pa) * PAGE_SIZE, &kv_any, &kp_none, - &kd_avoidalias); - if (!rwva) - panic("_rs_clearseed"); + pmap_kenter_pa(rwva, pa, PROT_READ | PROT_WRITE); + pmap_update(pmap_kernel()); - va = rwva; - for (i = 0; i < nitems(pa); i++, va += PAGE_SIZE) - pmap_kenter_pa(va, pa[i], PROT_READ | PROT_WRITE); - pmap_update(pmap_kernel()); + len = MIN(s, PAGE_SIZE - off); + explicit_bzero((void *)(rwva + off), len); - explicit_bzero((void *)(rwva + off), s); + pmap_kremove(rwva, PAGE_SIZE); + km_free((void *)rwva, PAGE_SIZE, &kv_any, &kp_none); - pmap_kremove(rwva, nitems(pa) * PAGE_SIZE); - km_free((void *)rwva, nitems(pa) * PAGE_SIZE, &kv_any, &kp_none); + va += PAGE_SIZE; + s -= len; + off = 0; + } } static inline void |