[lvc-project] [PATCH] nvdimm: add extra LBA check for map read and write operations

Ira Weiny ira.weiny at intel.com
Thu Dec 19 01:29:40 MSK 2024


Dmitry Antipov wrote:
> In 'btt_map_read()' and '__btt_map_write()', add an extra check
> whether requested LBA may be represented as valid offset against
> an offset of the map area of the given arena. Compile tested only.

Does this fix a real problem?

Ira

> 
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
> 
> Signed-off-by: Dmitry Antipov <dmantipov at yandex.ru>
> ---
>  drivers/nvdimm/btt.c | 18 +++++++++++++-----
>  1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
> index 423dcd190906..2bd03143c8c3 100644
> --- a/drivers/nvdimm/btt.c
> +++ b/drivers/nvdimm/btt.c
> @@ -96,12 +96,17 @@ static int btt_info_read(struct arena_info *arena, struct btt_sb *super)
>  static int __btt_map_write(struct arena_info *arena, u32 lba, __le32 mapping,
>  		unsigned long flags)
>  {
> -	u64 ns_off = arena->mapoff + (lba * MAP_ENT_SIZE);
> +	u32 lba_off;
> +	u64 ns_off;
>  
> -	if (unlikely(lba >= arena->external_nlba))
> +	if (unlikely(lba >= arena->external_nlba ||
> +		     check_mul_overflow(lba, MAP_ENT_SIZE, &lba_off)))
>  		dev_err_ratelimited(to_dev(arena),
>  			"%s: lba %#x out of range (max: %#x)\n",
>  			__func__, lba, arena->external_nlba);
> +
> +	ns_off = arena->mapoff + lba_off;
> +
>  	return arena_write_bytes(arena, ns_off, &mapping, MAP_ENT_SIZE, flags);
>  }
>  
> @@ -154,14 +159,17 @@ static int btt_map_read(struct arena_info *arena, u32 lba, u32 *mapping,
>  {
>  	int ret;
>  	__le32 in;
> -	u32 raw_mapping, postmap, ze, z_flag, e_flag;
> -	u64 ns_off = arena->mapoff + (lba * MAP_ENT_SIZE);
> +	u64 ns_off;
> +	u32 raw_mapping, postmap, ze, z_flag, e_flag, lba_off;
>  
> -	if (unlikely(lba >= arena->external_nlba))
> +	if (unlikely(lba >= arena->external_nlba ||
> +		     check_mul_overflow(lba, MAP_ENT_SIZE, &lba_off)))
>  		dev_err_ratelimited(to_dev(arena),
>  			"%s: lba %#x out of range (max: %#x)\n",
>  			__func__, lba, arena->external_nlba);
>  
> +	ns_off = arena->mapoff + lba_off;
> +
>  	ret = arena_read_bytes(arena, ns_off, &in, MAP_ENT_SIZE, rwb_flags);
>  	if (ret)
>  		return ret;
> -- 
> 2.47.1
> 





More information about the lvc-project mailing list