diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2008-04-12 20:37:37 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2008-04-12 20:37:37 +0000 |
commit | 64d661631ff2715f9b53bc2aa2ff1fe90f4a8b23 (patch) | |
tree | d8cbf001c20217258bb547f764a3f6b55bcd1a92 /sys/uvm | |
parent | 15180c410d235285778f8c09233a4279f9b18870 (diff) |
Prune the in-use swap encryption keys in uvm_shutdown(), per deraadt@'s idea.
Diffstat (limited to 'sys/uvm')
-rw-r--r-- | sys/uvm/uvm_page.c | 5 | ||||
-rw-r--r-- | sys/uvm/uvm_swap.c | 46 | ||||
-rw-r--r-- | sys/uvm/uvm_swap.h | 3 |
3 files changed, 46 insertions, 8 deletions
diff --git a/sys/uvm/uvm_page.c b/sys/uvm/uvm_page.c index 0c401692408..1c05a735763 100644 --- a/sys/uvm/uvm_page.c +++ b/sys/uvm/uvm_page.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_page.c,v 1.65 2008/04/09 16:58:11 deraadt Exp $ */ +/* $OpenBSD: uvm_page.c,v 1.66 2008/04/12 20:37:35 miod Exp $ */ /* $NetBSD: uvm_page.c,v 1.44 2000/11/27 08:40:04 chs Exp $ */ /* @@ -882,6 +882,9 @@ uvm_page_physdump() void uvm_shutdown(void) { +#ifdef UVM_SWAP_ENCRYPT + uvm_swap_finicrypt_all(); +#endif } /* diff --git a/sys/uvm/uvm_swap.c b/sys/uvm/uvm_swap.c index 105d25f33d7..06d5473f2b4 100644 --- a/sys/uvm/uvm_swap.c +++ b/sys/uvm/uvm_swap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_swap.c,v 1.77 2008/04/12 20:36:38 miod Exp $ */ +/* $OpenBSD: uvm_swap.c,v 1.78 2008/04/12 20:37:36 miod Exp $ */ /* $NetBSD: uvm_swap.c,v 1.40 2000/11/17 11:39:39 mrg Exp $ */ /* @@ -151,7 +151,6 @@ struct swapdev { #define SWD_DCRYPT_SIZE(x) (SWD_DCRYPT_OFF((x) + SWD_DCRYPT_MASK) * sizeof(u_int32_t)) u_int32_t *swd_decrypt; /* bitmap for decryption */ struct swap_key *swd_keys; /* keys for different parts */ - int swd_nkeys; /* active keys */ #endif }; @@ -352,7 +351,6 @@ uvm_swap_initcrypt(struct swapdev *sdp, int npages) M_WAITOK|M_ZERO); sdp->swd_keys = malloc((npages >> SWD_KEY_SHIFT) * sizeof(struct swap_key), M_VMSWAP, M_WAITOK|M_ZERO); - sdp->swd_nkeys = 0; } boolean_t @@ -442,7 +440,34 @@ uvm_swap_needdecrypt(struct swapdev *sdp, int off) return sdp->swd_decrypt[SWD_DCRYPT_OFF(off)] & (1 << SWD_DCRYPT_BIT(off)) ? TRUE : FALSE; } + +void +uvm_swap_finicrypt_all(void) +{ + struct swapdev *sdp; + struct swappri *spp; + struct swap_key *key; + unsigned int nkeys; + + simple_lock(&uvm.swap_data_lock); + + LIST_FOREACH(spp, &swap_priority, spi_swappri) { + CIRCLEQ_FOREACH(sdp, &spp->spi_swapdev, swd_next) { + if (sdp->swd_decrypt == NULL) + continue; + + nkeys = dbtob((uint64_t)sdp->swd_nblks) >> PAGE_SHIFT; + key = sdp->swd_keys + ((nkeys >> SWD_KEY_SHIFT) - 1); + do { + if (key->refcount != 0) + swap_key_delete(key); + } while (key-- != sdp->swd_keys); + } + } + simple_unlock(&uvm.swap_data_lock); +} #endif /* UVM_SWAP_ENCRYPT */ + /* * swaplist functions: functions that operate on the list of swap * devices on the system. @@ -1708,8 +1733,13 @@ uvm_swap_free(startslot, nslots) if (swap_encrypt_initialized) { /* Dereference keys */ for (i = 0; i < nslots; i++) - if (uvm_swap_needdecrypt(sdp, startslot + i)) - SWAP_KEY_PUT(sdp, SWD_KEY(sdp, startslot + i)); + if (uvm_swap_needdecrypt(sdp, startslot + i)) { + struct swap_key *key; + + key = SWD_KEY(sdp, startslot + i); + if (key->refcount != 0) + SWAP_KEY_PUT(sdp, key); + } /* Mark range as not decrypt */ uvm_swap_markdecrypt(sdp, startslot, nslots, 0); @@ -2013,12 +2043,16 @@ uvm_swap_io(pps, startslot, npages, flags) int i; caddr_t data = bp->b_data; u_int64_t block = startblk; - struct swap_key *key = NULL; + struct swap_key *key; for (i = 0; i < npages; i++) { /* Check if we need to decrypt */ if (uvm_swap_needdecrypt(sdp, startslot + i)) { key = SWD_KEY(sdp, startslot + i); + if (key->refcount == 0) { + result = VM_PAGER_ERROR; + break; + } swap_decrypt(key, data, data, block, 1 << PAGE_SHIFT); } diff --git a/sys/uvm/uvm_swap.h b/sys/uvm/uvm_swap.h index 4eb33f5fef8..6ac5be986fa 100644 --- a/sys/uvm/uvm_swap.h +++ b/sys/uvm/uvm_swap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_swap.h,v 1.11 2002/03/14 01:27:19 millert Exp $ */ +/* $OpenBSD: uvm_swap.h,v 1.12 2008/04/12 20:37:36 miod Exp $ */ /* $NetBSD: uvm_swap.h,v 1.5 2000/01/11 06:57:51 chs Exp $ */ /* @@ -46,6 +46,7 @@ void uvm_swap_markbad(int, int); #ifdef UVM_SWAP_ENCRYPT void uvm_swap_initcrypt_all(void); void uvm_swap_freepages(struct vm_page **, int); +void uvm_swap_finicrypt_all(void); #endif #endif /* _KERNEL */ |