Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: e93912786e50 ("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>

authored by

Eric Biggers and committed by
Mikulas Patocka
d6d0e6b9 0f1e16b3

+3 -9
+3 -9
drivers/md/dm-table.c
··· 1237 1237 bdev_get_queue(bdev)->crypto_profile; 1238 1238 int err = -EOPNOTSUPP; 1239 1239 1240 - if (!args->err) 1241 - return 0; 1242 - 1243 1240 switch (args->op) { 1244 1241 case DERIVE_SW_SECRET: 1245 1242 err = blk_crypto_derive_sw_secret( ··· 1263 1266 break; 1264 1267 } 1265 1268 args->err = err; 1266 - 1267 - /* Try another device in case this fails. */ 1268 - return 0; 1269 + return 1; /* No need to continue the iteration. */ 1269 1270 } 1270 1271 1271 1272 static int dm_exec_wrappedkey_op(struct blk_crypto_profile *profile, ··· 1289 1294 * declared on all underlying devices. Thus, all the underlying devices 1290 1295 * should support all wrapped key operations and they should behave 1291 1296 * identically, i.e. work with the same keys. So, just executing the 1292 - * operation on the first device on which it works suffices for now. 1297 + * operation on the first device suffices for now. 1293 1298 */ 1294 1299 for (i = 0; i < t->num_targets; i++) { 1295 1300 ti = dm_table_get_target(t, i); 1296 1301 if (!ti->type->iterate_devices) 1297 1302 continue; 1298 - ti->type->iterate_devices(ti, dm_wrappedkey_op_callback, args); 1299 - if (!args->err) 1303 + if (ti->type->iterate_devices(ti, dm_wrappedkey_op_callback, args) != 0) 1300 1304 break; 1301 1305 } 1302 1306 out: