[dm-devel] [BUG] Oops caused by FEC in 4.10.0

Milan Broz mbroz at redhat.com
Thu Mar 16 07:15:49 UTC 2017


On 03/15/2017 11:12 PM, Sami Tolvanen wrote:
> On Wed, Mar 15, 2017 at 09:22:02PM +0100, michal virgovic wrote:
>> This oops keeps appearing.
> 
> This can happen if dm-verity is set up with an invalid root hash, for
> example. Please test the attached patch, which limits recursion and should
> allow it to fail more gracefully.
> 
> Sami

Thanks Sami!

I see these patches are already in Android, Why it is not upstream?
https://android.googlesource.com/kernel/goldfish/+/21c0fe9f24b7707d2b49401f8c740c3e35c580ea%5E%21/

We tried to finally implement FEC support in veritysetup and it would
be nice that upstream kernel contains all patches so we do not
need to reinvent the wheel...

Thanks,
Milan



> 
> ---
> 
> dm verity fec: limit error correction recursion
> 
> If the hash tree itself is sufficiently corrupt in addition to data blocks,
> it's possible for error correction to end up in a deep recursive loop,
> which eventually causes a kernel panic. This change limits the recursion to
> a reasonable level during a single I/O operation.
> 
> Fixes: a739ff3f543a ("dm verity: add support for forward error correction")
> Signed-off-by: Sami Tolvanen <samitolvanen at google.com>
> ---
>  drivers/md/dm-verity-fec.c | 12 +++++++++++-
>  drivers/md/dm-verity-fec.h |  4 ++++
>  2 files changed, 15 insertions(+), 1 deletion(-)
> 
> 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,
>  	if (!verity_fec_is_enabled(v))
>  		return -EOPNOTSUPP;
>  
> +	if (fio->level >= DM_VERITY_FEC_MAX_RECURSION) {
> +		DMWARN_LIMIT("%s: FEC: recursion too deep", v->data_dev->name);
> +		return -EIO;
> +	}
> +
> +	fio->level++;
> +
>  	if (type == DM_VERITY_BLOCK_TYPE_METADATA)
>  		block += v->data_blocks;
>  
> @@ -470,7 +477,7 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io,
>  	if (r < 0) {
>  		r = fec_decode_rsb(v, io, fio, rsb, offset, true);
>  		if (r < 0)
> -			return r;
> +			goto done;
>  	}
>  
>  	if (dest)
> @@ -480,6 +487,8 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io,
>  		r = verity_for_bv_block(v, io, iter, fec_bv_copy);
>  	}
>  
> +done:
> +	fio->level--;
>  	return r;
>  }
>  
> @@ -520,6 +529,7 @@ void verity_fec_init_io(struct dm_verity_io *io)
>  	memset(fio->bufs, 0, sizeof(fio->bufs));
>  	fio->nbufs = 0;
>  	fio->output = NULL;
> +	fio->level = 0;
>  }
>  
>  /*
> 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 @@
>  #define DM_VERITY_FEC_BUF_MAX \
>  	(1 << (PAGE_SHIFT - DM_VERITY_FEC_BUF_RS_BITS))
>  
> +/* maximum recursion level for verity_fec_decode */
> +#define DM_VERITY_FEC_MAX_RECURSION	4
> +
>  #define DM_VERITY_OPT_FEC_DEV		"use_fec_from_device"
>  #define DM_VERITY_OPT_FEC_BLOCKS	"fec_blocks"
>  #define DM_VERITY_OPT_FEC_START		"fec_start"
> @@ -58,6 +61,7 @@ struct dm_verity_fec_io {
>  	unsigned nbufs;		/* number of buffers allocated */
>  	u8 *output;		/* buffer for corrected output */
>  	size_t output_pos;
> +	unsigned level;		/* recursion level */
>  };
>  
>  #ifdef CONFIG_DM_VERITY_FEC
> 




More information about the dm-devel mailing list