| From 6b4db2e528f650c7fb712961aac36455468d5902 Mon Sep 17 00:00:00 2001 |
| From: Ido Schimmel <idosch@nvidia.com> |
| Date: Tue, 9 Aug 2022 14:35:06 +0300 |
| Subject: devlink: Fix use-after-free after a failed reload |
| |
| From: Ido Schimmel <idosch@nvidia.com> |
| |
| commit 6b4db2e528f650c7fb712961aac36455468d5902 upstream. |
| |
| After a failed devlink reload, devlink parameters are still registered, |
| which means user space can set and get their values. In the case of the |
| mlxsw "acl_region_rehash_interval" parameter, these operations will |
| trigger a use-after-free [1]. |
| |
| Fix this by rejecting set and get operations while in the failed state. |
| Return the "-EOPNOTSUPP" error code which does not abort the parameters |
| dump, but instead causes it to skip over the problematic parameter. |
| |
| Another possible fix is to perform these checks in the mlxsw parameter |
| callbacks, but other drivers might be affected by the same problem and I |
| am not aware of scenarios where these stricter checks will cause a |
| regression. |
| |
| [1] |
| mlxsw_spectrum3 0000:00:10.0: Port 125: Failed to register netdev |
| mlxsw_spectrum3 0000:00:10.0: Failed to create ports |
| |
| ================================================================== |
| BUG: KASAN: use-after-free in mlxsw_sp_acl_tcam_vregion_rehash_intrvl_get+0xbd/0xd0 drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c:904 |
| Read of size 4 at addr ffff8880099dcfd8 by task kworker/u4:4/777 |
| |
| CPU: 1 PID: 777 Comm: kworker/u4:4 Not tainted 5.19.0-rc7-custom-126601-gfe26f28c586d #1 |
| Hardware name: QEMU MSN4700, BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 |
| Workqueue: netns cleanup_net |
| Call Trace: |
| <TASK> |
| __dump_stack lib/dump_stack.c:88 [inline] |
| dump_stack_lvl+0x92/0xbd lib/dump_stack.c:106 |
| print_address_description mm/kasan/report.c:313 [inline] |
| print_report.cold+0x5e/0x5cf mm/kasan/report.c:429 |
| kasan_report+0xb9/0xf0 mm/kasan/report.c:491 |
| __asan_report_load4_noabort+0x14/0x20 mm/kasan/report_generic.c:306 |
| mlxsw_sp_acl_tcam_vregion_rehash_intrvl_get+0xbd/0xd0 drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c:904 |
| mlxsw_sp_acl_region_rehash_intrvl_get+0x49/0x60 drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c:1106 |
| mlxsw_sp_params_acl_region_rehash_intrvl_get+0x33/0x80 drivers/net/ethernet/mellanox/mlxsw/spectrum.c:3854 |
| devlink_param_get net/core/devlink.c:4981 [inline] |
| devlink_nl_param_fill+0x238/0x12d0 net/core/devlink.c:5089 |
| devlink_param_notify+0xe5/0x230 net/core/devlink.c:5168 |
| devlink_ns_change_notify net/core/devlink.c:4417 [inline] |
| devlink_ns_change_notify net/core/devlink.c:4396 [inline] |
| devlink_reload+0x15f/0x700 net/core/devlink.c:4507 |
| devlink_pernet_pre_exit+0x112/0x1d0 net/core/devlink.c:12272 |
| ops_pre_exit_list net/core/net_namespace.c:152 [inline] |
| cleanup_net+0x494/0xc00 net/core/net_namespace.c:582 |
| process_one_work+0x9fc/0x1710 kernel/workqueue.c:2289 |
| worker_thread+0x675/0x10b0 kernel/workqueue.c:2436 |
| kthread+0x30c/0x3d0 kernel/kthread.c:376 |
| ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:306 |
| </TASK> |
| |
| The buggy address belongs to the physical page: |
| page:ffffea0000267700 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x99dc |
| flags: 0x100000000000000(node=0|zone=1) |
| raw: 0100000000000000 0000000000000000 dead000000000122 0000000000000000 |
| raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 |
| page dumped because: kasan: bad access detected |
| |
| Memory state around the buggy address: |
| ffff8880099dce80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |
| ffff8880099dcf00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |
| >ffff8880099dcf80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |
| ^ |
| ffff8880099dd000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |
| ffff8880099dd080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |
| ================================================================== |
| |
| Fixes: 98bbf70c1c41 ("mlxsw: spectrum: add "acl_region_rehash_interval" devlink param") |
| Signed-off-by: Ido Schimmel <idosch@nvidia.com> |
| Reviewed-by: Jiri Pirko <jiri@nvidia.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/core/devlink.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/net/core/devlink.c |
| +++ b/net/core/devlink.c |
| @@ -4943,7 +4943,7 @@ static int devlink_param_get(struct devl |
| const struct devlink_param *param, |
| struct devlink_param_gset_ctx *ctx) |
| { |
| - if (!param->get) |
| + if (!param->get || devlink->reload_failed) |
| return -EOPNOTSUPP; |
| return param->get(devlink, param->id, ctx); |
| } |
| @@ -4952,7 +4952,7 @@ static int devlink_param_set(struct devl |
| const struct devlink_param *param, |
| struct devlink_param_gset_ctx *ctx) |
| { |
| - if (!param->set) |
| + if (!param->set || devlink->reload_failed) |
| return -EOPNOTSUPP; |
| return param->set(devlink, param->id, ctx); |
| } |