Skip to content

Commit d6d0e6b

Browse files
Eric BiggersMikulas Patocka
authored andcommitted
dm: fix excessive blk-crypto operations for invalid keys
dm_exec_wrappedkey_op() passes through the derive_sw_secret, import_key, generate_key, and prepare_key blk-crypto operations to an underlying device. Currently, it calls the operation on every underlying device until one returns success. This logic is flawed when the operation is expected to fail, such as an invalid key being passed to derive_sw_secret. That can happen if userspace passes an invalid key to the FS_IOC_ADD_ENCRYPTION_KEY ioctl. When that happens on a device-mapper device that consists of many dm-linear targets, a lot of unnecessary key unwrapping requests get sent to the underlying key wrapping hardware. Fix this by considering the first device only. As already documented in the comment, it was already checked that all underlying devices support wrapped keys, so this should be fine. Fixes: e939127 ("dm: pass through operations on wrapped inline crypto keys") Cc: stable@vger.kernel.org Signed-off-by: Eric Biggers <ebiggers@kernel.org> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
1 parent 0f1e16b commit d6d0e6b

1 file changed

Lines changed: 3 additions & 9 deletions

File tree

drivers/md/dm-table.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,9 +1237,6 @@ static int dm_wrappedkey_op_callback(struct dm_target *ti, struct dm_dev *dev,
12371237
bdev_get_queue(bdev)->crypto_profile;
12381238
int err = -EOPNOTSUPP;
12391239

1240-
if (!args->err)
1241-
return 0;
1242-
12431240
switch (args->op) {
12441241
case DERIVE_SW_SECRET:
12451242
err = blk_crypto_derive_sw_secret(
@@ -1266,9 +1263,7 @@ static int dm_wrappedkey_op_callback(struct dm_target *ti, struct dm_dev *dev,
12661263
break;
12671264
}
12681265
args->err = err;
1269-
1270-
/* Try another device in case this fails. */
1271-
return 0;
1266+
return 1; /* No need to continue the iteration. */
12721267
}
12731268

12741269
static int dm_exec_wrappedkey_op(struct blk_crypto_profile *profile,
@@ -1294,14 +1289,13 @@ static int dm_exec_wrappedkey_op(struct blk_crypto_profile *profile,
12941289
* declared on all underlying devices. Thus, all the underlying devices
12951290
* should support all wrapped key operations and they should behave
12961291
* identically, i.e. work with the same keys. So, just executing the
1297-
* operation on the first device on which it works suffices for now.
1292+
* operation on the first device suffices for now.
12981293
*/
12991294
for (i = 0; i < t->num_targets; i++) {
13001295
ti = dm_table_get_target(t, i);
13011296
if (!ti->type->iterate_devices)
13021297
continue;
1303-
ti->type->iterate_devices(ti, dm_wrappedkey_op_callback, args);
1304-
if (!args->err)
1298+
if (ti->type->iterate_devices(ti, dm_wrappedkey_op_callback, args) != 0)
13051299
break;
13061300
}
13071301
out:

0 commit comments

Comments
 (0)