summaryrefslogtreecommitdiff
path: root/sys/uvm
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2008-04-12 20:37:37 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2008-04-12 20:37:37 +0000
commit64d661631ff2715f9b53bc2aa2ff1fe90f4a8b23 (patch)
treed8cbf001c20217258bb547f764a3f6b55bcd1a92 /sys/uvm
parent15180c410d235285778f8c09233a4279f9b18870 (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.c5
-rw-r--r--sys/uvm/uvm_swap.c46
-rw-r--r--sys/uvm/uvm_swap.h3
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 */