diff options
-rw-r--r-- | drivers/md/dm-verity-fec.c | 12 | ||||
-rw-r--r-- | drivers/md/dm-verity-fec.h | 4 |
2 files changed, 15 insertions, 1 deletions
diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c index 0f0eb8a3d922..c3cc04d89524 100644 --- a/drivers/md/dm-verity-fec.c +++ b/drivers/md/dm-verity-fec.c | |||
@@ -439,6 +439,13 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, | |||
439 | if (!verity_fec_is_enabled(v)) | 439 | if (!verity_fec_is_enabled(v)) |
440 | return -EOPNOTSUPP; | 440 | return -EOPNOTSUPP; |
441 | 441 | ||
442 | if (fio->level >= DM_VERITY_FEC_MAX_RECURSION) { | ||
443 | DMWARN_LIMIT("%s: FEC: recursion too deep", v->data_dev->name); | ||
444 | return -EIO; | ||
445 | } | ||
446 | |||
447 | fio->level++; | ||
448 | |||
442 | if (type == DM_VERITY_BLOCK_TYPE_METADATA) | 449 | if (type == DM_VERITY_BLOCK_TYPE_METADATA) |
443 | block += v->data_blocks; | 450 | block += v->data_blocks; |
444 | 451 | ||
@@ -470,7 +477,7 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, | |||
470 | if (r < 0) { | 477 | if (r < 0) { |
471 | r = fec_decode_rsb(v, io, fio, rsb, offset, true); | 478 | r = fec_decode_rsb(v, io, fio, rsb, offset, true); |
472 | if (r < 0) | 479 | if (r < 0) |
473 | return r; | 480 | goto done; |
474 | } | 481 | } |
475 | 482 | ||
476 | if (dest) | 483 | if (dest) |
@@ -480,6 +487,8 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, | |||
480 | r = verity_for_bv_block(v, io, iter, fec_bv_copy); | 487 | r = verity_for_bv_block(v, io, iter, fec_bv_copy); |
481 | } | 488 | } |
482 | 489 | ||
490 | done: | ||
491 | fio->level--; | ||
483 | return r; | 492 | return r; |
484 | } | 493 | } |
485 | 494 | ||
@@ -520,6 +529,7 @@ void verity_fec_init_io(struct dm_verity_io *io) | |||
520 | memset(fio->bufs, 0, sizeof(fio->bufs)); | 529 | memset(fio->bufs, 0, sizeof(fio->bufs)); |
521 | fio->nbufs = 0; | 530 | fio->nbufs = 0; |
522 | fio->output = NULL; | 531 | fio->output = NULL; |
532 | fio->level = 0; | ||
523 | } | 533 | } |
524 | 534 | ||
525 | /* | 535 | /* |
diff --git a/drivers/md/dm-verity-fec.h b/drivers/md/dm-verity-fec.h index 7fa0298b995e..bb31ce87a933 100644 --- a/drivers/md/dm-verity-fec.h +++ b/drivers/md/dm-verity-fec.h | |||
@@ -27,6 +27,9 @@ | |||
27 | #define DM_VERITY_FEC_BUF_MAX \ | 27 | #define DM_VERITY_FEC_BUF_MAX \ |
28 | (1 << (PAGE_SHIFT - DM_VERITY_FEC_BUF_RS_BITS)) | 28 | (1 << (PAGE_SHIFT - DM_VERITY_FEC_BUF_RS_BITS)) |
29 | 29 | ||
30 | /* maximum recursion level for verity_fec_decode */ | ||
31 | #define DM_VERITY_FEC_MAX_RECURSION 4 | ||
32 | |||
30 | #define DM_VERITY_OPT_FEC_DEV "use_fec_from_device" | 33 | #define DM_VERITY_OPT_FEC_DEV "use_fec_from_device" |
31 | #define DM_VERITY_OPT_FEC_BLOCKS "fec_blocks" | 34 | #define DM_VERITY_OPT_FEC_BLOCKS "fec_blocks" |
32 | #define DM_VERITY_OPT_FEC_START "fec_start" | 35 | #define DM_VERITY_OPT_FEC_START "fec_start" |
@@ -58,6 +61,7 @@ struct dm_verity_fec_io { | |||
58 | unsigned nbufs; /* number of buffers allocated */ | 61 | unsigned nbufs; /* number of buffers allocated */ |
59 | u8 *output; /* buffer for corrected output */ | 62 | u8 *output; /* buffer for corrected output */ |
60 | size_t output_pos; | 63 | size_t output_pos; |
64 | unsigned level; /* recursion level */ | ||
61 | }; | 65 | }; |
62 | 66 | ||
63 | #ifdef CONFIG_DM_VERITY_FEC | 67 | #ifdef CONFIG_DM_VERITY_FEC |