Download raw body.
sys/swap: avoid double encryption for crypto volume
On 2026/04/10 15:33, Kirill A. Korinsky wrote:
> 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?
I think that's intentional. swap encryption means that the swap on disk
is unreadable after a reboot (and I'm not sure how things work with key
rotation but possibly after some time expires too?).
With softraid crypto, it will be readable after reboot if you have the
softraid key.
You can always set vm.swapencrypt.enable=0 if that's good enough for your
security posture.
>
> 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
>
sys/swap: avoid double encryption for crypto volume