Index | Thread | Search

From:
Kirill A. Korinsky <kirill@korins.ky>
Subject:
sys/swap: avoid double encryption for crypto volume
To:
OpenBSD tech <tech@openbsd.org>
Date:
Fri, 10 Apr 2026 15:33:39 +0200

Download raw body.

Thread
tech@,

I had noticed that we may encrypt swap twice when it is stroed on softraid
crypto.

Here a diff which disabled swapencrypt for volume which is stored on crypto
softraid.

Thoughts? Tests? OK to commit after release?


Index: sys/dev/softraid.c
===================================================================
RCS file: /home/cvs/src/sys/dev/softraid.c,v
diff -u -p -r1.438 softraid.c
--- sys/dev/softraid.c	18 Oct 2025 15:33:19 -0000	1.438
+++ sys/dev/softraid.c	10 Apr 2026 13:26:20 -0000
@@ -4842,6 +4842,32 @@ sr_find_discipline(struct sr_softc *sc, 
 	return sd;
 }
 
+int
+sr_crypto_volume(dev_t dev)
+{
+	struct sr_discipline	*sd;
+	struct disk		*dk;
+	dev_t			rawdev;
+
+	if (softraid0 == NULL)
+		return 0;
+
+	rawdev = MAKEDISKDEV(major(dev), DISKUNIT(dev), RAW_PART);
+	TAILQ_FOREACH(dk, &disklist, dk_link) {
+		if (dk->dk_devno != rawdev)
+			continue;
+		if (dk->dk_name == NULL)
+			return 0;
+		sd = sr_find_discipline(softraid0, dk->dk_name);
+		if (sd == NULL)
+			return 0;
+		return sd->sd_type == SR_MD_CRYPTO ||
+		    sd->sd_type == SR_MD_RAID1C;
+	}
+
+	return 0;
+}
+
 #ifndef SMALL_KERNEL
 int
 sr_sensors_create(struct sr_discipline *sd)
Index: sys/uvm/uvm_swap.c
===================================================================
RCS file: /home/cvs/src/sys/uvm/uvm_swap.c,v
diff -u -p -r1.179 uvm_swap.c
--- sys/uvm/uvm_swap.c	11 Feb 2026 22:34:41 -0000	1.179
+++ sys/uvm/uvm_swap.c	10 Apr 2026 13:26:20 -0000
@@ -67,6 +67,11 @@
 #include <sys/specdev.h>
 
 #include "vnd.h"
+#include "softraid.h"
+
+#if NSOFTRAID > 0
+int sr_crypto_volume(dev_t);
+#endif
 
 /*
  * uvm_swap.c: manage configuration and i/o to swap space.
@@ -161,6 +166,7 @@ struct swapdev {
 #define SWD_DCRYPT_OFF(x)	((x) >> SWD_DCRYPT_SHIFT)
 #define SWD_DCRYPT_BIT(x)	((x) & SWD_DCRYPT_MASK)
 #define SWD_DCRYPT_SIZE(x)	(SWD_DCRYPT_OFF((x) + SWD_DCRYPT_MASK) * sizeof(u_int32_t))
+	int			swd_doswapencrypt;
 	u_int32_t		*swd_decrypt;	/* bitmap for decryption */
 	struct swap_key		*swd_keys;	/* keys for different parts */
 #endif
@@ -301,7 +307,7 @@ uvm_swap_initcrypt_all(void)
 
 	LIST_FOREACH(spp, &swap_priority, spi_swappri) {
 		TAILQ_FOREACH(sdp, &spp->spi_swapdev, swd_next) {
-			if (sdp->swd_decrypt == NULL) {
+			if (sdp->swd_doswapencrypt && sdp->swd_decrypt == NULL) {
 				npages = dbtob((uint64_t)sdp->swd_nblks) >>
 				    PAGE_SHIFT;
 				uvm_swap_initcrypt(sdp, npages);
@@ -371,7 +377,7 @@ uvm_swap_markdecrypt(struct swapdev *sdp
 	int pagestart, i;
 	int off, bit;
 
-	if (!sdp)
+	if (!sdp || sdp->swd_decrypt == NULL)
 		return;
 
 	pagestart = startslot - sdp->swd_drumoffset;
@@ -394,7 +400,7 @@ uvm_swap_markdecrypt(struct swapdev *sdp
 boolean_t
 uvm_swap_needdecrypt(struct swapdev *sdp, int off)
 {
-	if (!sdp)
+	if (!sdp || sdp->swd_decrypt == NULL)
 		return FALSE;
 
 	off -= sdp->swd_drumoffset;
@@ -974,7 +980,12 @@ swap_on(struct proc *p, struct swapdev *
 	vref(vp);
 
 #ifdef UVM_SWAP_ENCRYPT
-	if (uvm_doswapencrypt)
+	sdp->swd_doswapencrypt = 1;
+#if NSOFTRAID > 0
+	if (vp->v_type == VBLK && sr_crypto_volume(dev))
+		sdp->swd_doswapencrypt = 0;
+#endif
+	if (uvm_doswapencrypt && sdp->swd_doswapencrypt)
 		uvm_swap_initcrypt(sdp, npages);
 #endif
 	/* now add the new swapdev to the drum and enable. */
@@ -1704,6 +1715,8 @@ uvm_swap_io(struct vm_page **pps, int st
 		mtx_enter(&uvm_swap_data_lock);
 		sdp = swapdrum_getsdp(startslot);
 		mtx_leave(&uvm_swap_data_lock);
+		if (encrypt && sdp != NULL && !sdp->swd_doswapencrypt)
+			encrypt = 0;
 	}
 
 	/*


-- 
wbr, Kirill