Fix a long standing off-by-one bug in the softraid crypto number of keys
authorjsing <jsing@openbsd.org>
Mon, 12 Jun 2017 14:46:00 +0000 (14:46 +0000)
committerjsing <jsing@openbsd.org>
Mon, 12 Jun 2017 14:46:00 +0000 (14:46 +0000)
calculation - we allow one key per 0.5TB, which should allow up to 16TB
disks, however the disk size was treated like a block offset and shifted.
This meant that the maximum size was actually 16TB minus one block.

While here also calculate the number of keys as an absolute value, rather
than as the upper inclusive bound - adjust the logic in the associated for
and if statements to match.

ok krw@ tb@

sys/dev/softraid_crypto.c

index c419686..4e06ab0 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid_crypto.c,v 1.133 2017/02/07 17:25:46 patrick Exp $ */
+/* $OpenBSD: softraid_crypto.c,v 1.134 2017/06/12 14:46:00 jsing Exp $ */
 /*
  * Copyright (c) 2007 Marco Peereboom <marco@peereboom.us>
  * Copyright (c) 2008 Hans-Joerg Hoexer <hshoexer@openbsd.org>
@@ -948,10 +948,11 @@ sr_crypto_alloc_resources(struct sr_discipline *sd)
        cri.cri_klen = sd->mds.mdd_crypto.scr_klen;
 
        /* Allocate a session for every 2^SR_CRYPTO_KEY_BLKSHIFT blocks. */
-       num_keys = sd->sd_meta->ssdi.ssd_size >> SR_CRYPTO_KEY_BLKSHIFT;
-       if (num_keys >= SR_CRYPTO_MAXKEYS)
+       num_keys = ((sd->sd_meta->ssdi.ssd_size - 1) >>
+           SR_CRYPTO_KEY_BLKSHIFT) + 1;
+       if (num_keys > SR_CRYPTO_MAXKEYS)
                return (EFBIG);
-       for (i = 0; i <= num_keys; i++) {
+       for (i = 0; i < num_keys; i++) {
                cri.cri_key = sd->mds.mdd_crypto.scr_key[i];
                if (crypto_newsession(&sd->mds.mdd_crypto.scr_sid[i],
                    &cri, 0) != 0) {