Blob Blame History Raw
From 1d593a76796574845d7e32aaadd9f7d1ed4e7987 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 12 Jul 2022 18:07:25 +0100
Subject: [PATCH] luks: Avoid potential overflow when computing key material
 offset and length

Found by Coverity:

  Error: OVERFLOW_BEFORE_WIDEN (CWE-190): [#def58]
  nbdkit-1.30.7/filters/luks/luks-encryption.c:558: overflow_before_widen: Potentially overflowing expression "h->phdr.master_key_len * h->phdr.keyslot[i].stripes" with type "unsigned int" (32 bits, unsigned) is evaluated using 32-bit arithmetic, and then used in a context that expects an expression of type "uint64_t" (64 bits, unsigned).
  nbdkit-1.30.7/filters/luks/luks-encryption.c:558: remediation: To avoid overflow, cast either "h->phdr.master_key_len" or "h->phdr.keyslot[i].stripes" to type "uint64_t".
  #  556|     uint64_t len, r;
  #  557|
  #  558|->   len = h->phdr.master_key_len * h->phdr.keyslot[i].stripes;
  #  559|     r = DIV_ROUND_UP (len, LUKS_SECTOR_SIZE);
  #  560|     r = ROUND_UP (r, LUKS_ALIGN_KEYSLOTS / LUKS_SECTOR_SIZE);

  Error: OVERFLOW_BEFORE_WIDEN (CWE-190): [#def62]
  nbdkit-1.30.7/filters/luks/luks-encryption.c:616: overflow_before_widen: Potentially overflowing expression "ks->key_material_offset * 512U" with type "unsigned int" (32 bits, unsigned) is evaluated using 32-bit arithmetic, and then used in a context that expects an expression of type "uint64_t" (64 bits, unsigned).
  nbdkit-1.30.7/filters/luks/luks-encryption.c:616: remediation: To avoid overflow, cast either "ks->key_material_offset" or "512U" to type "uint64_t".
  #  614|
  #  615|     /* Read master key material from plugin. */
  #  616|->   start = ks->key_material_offset * LUKS_SECTOR_SIZE;
  #  617|     if (next->pread (next, split_key, split_key_len, start, 0, &err) == -1) {
  #  618|       errno = err;

Fixes: commit 468919dce6c5eb57503eacac0f67e5dd87c58e6c
(cherry picked from commit 808d88fbc7b58b7c95e05f41fec729cba92ef518)
---
 filters/luks/luks-encryption.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/filters/luks/luks-encryption.c b/filters/luks/luks-encryption.c
index 19aaf06a..06435b27 100644
--- a/filters/luks/luks-encryption.c
+++ b/filters/luks/luks-encryption.c
@@ -561,7 +561,7 @@ key_material_length_in_sectors (struct luks_data *h, size_t i)
 {
   uint64_t len, r;
 
-  len = h->phdr.master_key_len * h->phdr.keyslot[i].stripes;
+  len = (uint64_t) h->phdr.master_key_len * h->phdr.keyslot[i].stripes;
   r = DIV_ROUND_UP (len, LUKS_SECTOR_SIZE);
   r = ROUND_UP (r, LUKS_ALIGN_KEYSLOTS / LUKS_SECTOR_SIZE);
   return r;
@@ -619,7 +619,7 @@ try_passphrase_in_keyslot (nbdkit_next *next, struct luks_data *h,
   }
 
   /* Read master key material from plugin. */
-  start = ks->key_material_offset * LUKS_SECTOR_SIZE;
+  start = (uint64_t) ks->key_material_offset * LUKS_SECTOR_SIZE;
   if (next->pread (next, split_key, split_key_len, start, 0, &err) == -1) {
     errno = err;
     return -1;
-- 
2.31.1