diff mbox series

nfp: fix use-after-free in area_cache_get()

Message ID 20220806143043.106787-1-wangjialiang0806@163.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series nfp: fix use-after-free in area_cache_get() | expand

Checks

Context Check Description
netdev/tree_selection success Guessed tree name to be net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix warning Target tree name not specified in the subject
netdev/cover_letter success Single patches do not need cover letters
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers success CCed 9 of 9 maintainers
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch warning CHECK: Alignment should match open parenthesis
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Jialiang Wang Aug. 6, 2022, 2:30 p.m. UTC
area_cache_get() calls cpp->op->area_init() and uses cache->area by
 nfp_cpp_area_priv(area), but in
 nfp_cpp_area_release()->nfp_cpp_area_put()->__release_cpp_area() we
 already freed the cache->area.

To avoid the use-after-free, reallocate a piece of memory for the
 cache->area by nfp_cpp_area_alloc().

Note: This vulnerability is triggerable by providing emulated device
 equipped with specified configuration.

BUG: KASAN: use-after-free in nfp6000_area_init+0x74/0x1d0 [nfp]
Write of size 4 at addr ffff888005b490a0 by task insmod/226
Call Trace:
  <TASK>
  dump_stack_lvl+0x33/0x46
  print_report.cold.12+0xb2/0x6b7
  ? nfp6000_area_init+0x74/0x1d0 [nfp]
  kasan_report+0xa5/0x120
  ? nfp6000_area_init+0x74/0x1d0 [nfp]
  nfp6000_area_init+0x74/0x1d0 [nfp]
  area_cache_get.constprop.8+0x2da/0x360 [nfp]

Signed-off-by: Jialiang Wang <wangjialiang0806@163.com>
---
 drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

Jakub Kicinski Aug. 8, 2022, 7:15 p.m. UTC | #1
On Sat,  6 Aug 2022 22:30:43 +0800 Jialiang Wang wrote:
> area_cache_get() calls cpp->op->area_init() and uses cache->area by
>  nfp_cpp_area_priv(area), but in
>  nfp_cpp_area_release()->nfp_cpp_area_put()->__release_cpp_area() we
>  already freed the cache->area.
> 
> To avoid the use-after-free, reallocate a piece of memory for the
>  cache->area by nfp_cpp_area_alloc().
> 
> Note: This vulnerability is triggerable by providing emulated device
>  equipped with specified configuration.
> 
> BUG: KASAN: use-after-free in nfp6000_area_init+0x74/0x1d0 [nfp]
> Write of size 4 at addr ffff888005b490a0 by task insmod/226
> Call Trace:
>   <TASK>
>   dump_stack_lvl+0x33/0x46
>   print_report.cold.12+0xb2/0x6b7
>   ? nfp6000_area_init+0x74/0x1d0 [nfp]
>   kasan_report+0xa5/0x120
>   ? nfp6000_area_init+0x74/0x1d0 [nfp]
>   nfp6000_area_init+0x74/0x1d0 [nfp]
>   area_cache_get.constprop.8+0x2da/0x360 [nfp]

Please provide more of the report, including the allocated at and freed
at sections and run the thing thru stack decode so we get the line
numbers.
Yinjun Zhang Aug. 9, 2022, 7:08 a.m. UTC | #2
On Sat,  6 Aug 2022 22:30:43 +0800 Jialiang Wang wrote:
> area_cache_get() calls cpp->op->area_init() and uses cache->area by
>  nfp_cpp_area_priv(area), but in
>  nfp_cpp_area_release()->nfp_cpp_area_put()->__release_cpp_area() we
>  already freed the cache->area.

It frees only under condition that `area->kref` refcount is zero. But in normal path,
the refcount is incremented by calling `nfp_cpp_area_acquire` when `cache->id`
is not zero. So it's OK to release once when `cache->id` is not zero.

But it does have some problem in error path when `area_init` or `area_acquire`
fails, in which case `cache->id` is already set but refcount is not incremented as
expected. So we need set `cache->id` after everything is done.

So your current fix is not appropriate. Anyway thanks for bringing this to table,
I think you can resubmit a v2 to fix it?

> 
> To avoid the use-after-free, reallocate a piece of memory for the
>  cache->area by nfp_cpp_area_alloc().
> 
> Note: This vulnerability is triggerable by providing emulated device
>  equipped with specified configuration.
> 
> BUG: KASAN: use-after-free in nfp6000_area_init+0x74/0x1d0 [nfp]
> Write of size 4 at addr ffff888005b490a0 by task insmod/226
> Call Trace:
>   <TASK>
>   dump_stack_lvl+0x33/0x46
>   print_report.cold.12+0xb2/0x6b7
>   ? nfp6000_area_init+0x74/0x1d0 [nfp]
>   kasan_report+0xa5/0x120
>   ? nfp6000_area_init+0x74/0x1d0 [nfp]
>   nfp6000_area_init+0x74/0x1d0 [nfp]
>   area_cache_get.constprop.8+0x2da/0x360 [nfp]
> 
> Signed-off-by: Jialiang Wang <wangjialiang0806@163.com>
> ---
>  drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c
> b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c
> index 34c0d2ddf9ef..99091f24d2ba 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c
> +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c
> @@ -871,6 +871,10 @@ area_cache_get(struct nfp_cpp *cpp, u32 id,
>  		nfp_cpp_area_release(cache->area);
>  		cache->id = 0;
>  		cache->addr = 0;
> +		cache->area = nfp_cpp_area_alloc(cpp,
> +						 NFP_CPP_ID(7,
> +						 NFP_CPP_ACTION_RW, 0),
> +						 0, cache->size);
>  	}
> 
>  	/* Adjust the start address to be cache size aligned */
> --
> 2.17.1
diff mbox series

Patch

diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c
index 34c0d2ddf9ef..99091f24d2ba 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c
@@ -871,6 +871,10 @@  area_cache_get(struct nfp_cpp *cpp, u32 id,
 		nfp_cpp_area_release(cache->area);
 		cache->id = 0;
 		cache->addr = 0;
+		cache->area = nfp_cpp_area_alloc(cpp,
+						 NFP_CPP_ID(7,
+						 NFP_CPP_ACTION_RW, 0),
+						 0, cache->size);
 	}
 
 	/* Adjust the start address to be cache size aligned */