Patch "net/mlx5: Fix possible use-after-free in async command interface" has been added to the 6.0-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net/mlx5: Fix possible use-after-free in async command interface

to the 6.0-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-mlx5-fix-possible-use-after-free-in-async-comman.patch
and it can be found in the queue-6.0 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit b699434f97605884b7926a654e53ec144701752b
Author: Tariq Toukan <tariqt@xxxxxxxxxx>
Date:   Wed Oct 26 14:51:45 2022 +0100

    net/mlx5: Fix possible use-after-free in async command interface
    
    [ Upstream commit bacd22df95147ed673bec4692ab2d4d585935241 ]
    
    mlx5_cmd_cleanup_async_ctx should return only after all its callback
    handlers were completed. Before this patch, the below race between
    mlx5_cmd_cleanup_async_ctx and mlx5_cmd_exec_cb_handler was possible and
    lead to a use-after-free:
    
    1. mlx5_cmd_cleanup_async_ctx is called while num_inflight is 2 (i.e.
       elevated by 1, a single inflight callback).
    2. mlx5_cmd_cleanup_async_ctx decreases num_inflight to 1.
    3. mlx5_cmd_exec_cb_handler is called, decreases num_inflight to 0 and
       is about to call wake_up().
    4. mlx5_cmd_cleanup_async_ctx calls wait_event, which returns
       immediately as the condition (num_inflight == 0) holds.
    5. mlx5_cmd_cleanup_async_ctx returns.
    6. The caller of mlx5_cmd_cleanup_async_ctx frees the mlx5_async_ctx
       object.
    7. mlx5_cmd_exec_cb_handler goes on and calls wake_up() on the freed
       object.
    
    Fix it by syncing using a completion object. Mark it completed when
    num_inflight reaches 0.
    
    Trace:
    
    BUG: KASAN: use-after-free in do_raw_spin_lock+0x23d/0x270
    Read of size 4 at addr ffff888139cd12f4 by task swapper/5/0
    
    CPU: 5 PID: 0 Comm: swapper/5 Not tainted 6.0.0-rc3_for_upstream_debug_2022_08_30_13_10 #1
    Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
    Call Trace:
     <IRQ>
     dump_stack_lvl+0x57/0x7d
     print_report.cold+0x2d5/0x684
     ? do_raw_spin_lock+0x23d/0x270
     kasan_report+0xb1/0x1a0
     ? do_raw_spin_lock+0x23d/0x270
     do_raw_spin_lock+0x23d/0x270
     ? rwlock_bug.part.0+0x90/0x90
     ? __delete_object+0xb8/0x100
     ? lock_downgrade+0x6e0/0x6e0
     _raw_spin_lock_irqsave+0x43/0x60
     ? __wake_up_common_lock+0xb9/0x140
     __wake_up_common_lock+0xb9/0x140
     ? __wake_up_common+0x650/0x650
     ? destroy_tis_callback+0x53/0x70 [mlx5_core]
     ? kasan_set_track+0x21/0x30
     ? destroy_tis_callback+0x53/0x70 [mlx5_core]
     ? kfree+0x1ba/0x520
     ? do_raw_spin_unlock+0x54/0x220
     mlx5_cmd_exec_cb_handler+0x136/0x1a0 [mlx5_core]
     ? mlx5_cmd_cleanup_async_ctx+0x220/0x220 [mlx5_core]
     ? mlx5_cmd_cleanup_async_ctx+0x220/0x220 [mlx5_core]
     mlx5_cmd_comp_handler+0x65a/0x12b0 [mlx5_core]
     ? dump_command+0xcc0/0xcc0 [mlx5_core]
     ? lockdep_hardirqs_on_prepare+0x400/0x400
     ? cmd_comp_notifier+0x7e/0xb0 [mlx5_core]
     cmd_comp_notifier+0x7e/0xb0 [mlx5_core]
     atomic_notifier_call_chain+0xd7/0x1d0
     mlx5_eq_async_int+0x3ce/0xa20 [mlx5_core]
     atomic_notifier_call_chain+0xd7/0x1d0
     ? irq_release+0x140/0x140 [mlx5_core]
     irq_int_handler+0x19/0x30 [mlx5_core]
     __handle_irq_event_percpu+0x1f2/0x620
     handle_irq_event+0xb2/0x1d0
     handle_edge_irq+0x21e/0xb00
     __common_interrupt+0x79/0x1a0
     common_interrupt+0x78/0xa0
     </IRQ>
     <TASK>
     asm_common_interrupt+0x22/0x40
    RIP: 0010:default_idle+0x42/0x60
    Code: c1 83 e0 07 48 c1 e9 03 83 c0 03 0f b6 14 11 38 d0 7c 04 84 d2 75 14 8b 05 eb 47 22 02 85 c0 7e 07 0f 00 2d e0 9f 48 00 fb f4 <c3> 48 c7 c7 80 08 7f 85 e8 d1 d3 3e fe eb de 66 66 2e 0f 1f 84 00
    RSP: 0018:ffff888100dbfdf0 EFLAGS: 00000242
    RAX: 0000000000000001 RBX: ffffffff84ecbd48 RCX: 1ffffffff0afe110
    RDX: 0000000000000004 RSI: 0000000000000000 RDI: ffffffff835cc9bc
    RBP: 0000000000000005 R08: 0000000000000001 R09: ffff88881dec4ac3
    R10: ffffed1103bd8958 R11: 0000017d0ca571c9 R12: 0000000000000005
    R13: ffffffff84f024e0 R14: 0000000000000000 R15: dffffc0000000000
     ? default_idle_call+0xcc/0x450
     default_idle_call+0xec/0x450
     do_idle+0x394/0x450
     ? arch_cpu_idle_exit+0x40/0x40
     ? do_idle+0x17/0x450
     cpu_startup_entry+0x19/0x20
     start_secondary+0x221/0x2b0
     ? set_cpu_sibling_map+0x2070/0x2070
     secondary_startup_64_no_verify+0xcd/0xdb
     </TASK>
    
    Allocated by task 49502:
     kasan_save_stack+0x1e/0x40
     __kasan_kmalloc+0x81/0xa0
     kvmalloc_node+0x48/0xe0
     mlx5e_bulk_async_init+0x35/0x110 [mlx5_core]
     mlx5e_tls_priv_tx_list_cleanup+0x84/0x3e0 [mlx5_core]
     mlx5e_ktls_cleanup_tx+0x38f/0x760 [mlx5_core]
     mlx5e_cleanup_nic_tx+0xa7/0x100 [mlx5_core]
     mlx5e_detach_netdev+0x1ca/0x2b0 [mlx5_core]
     mlx5e_suspend+0xdb/0x140 [mlx5_core]
     mlx5e_remove+0x89/0x190 [mlx5_core]
     auxiliary_bus_remove+0x52/0x70
     device_release_driver_internal+0x40f/0x650
     driver_detach+0xc1/0x180
     bus_remove_driver+0x125/0x2f0
     auxiliary_driver_unregister+0x16/0x50
     mlx5e_cleanup+0x26/0x30 [mlx5_core]
     cleanup+0xc/0x4e [mlx5_core]
     __x64_sys_delete_module+0x2b5/0x450
     do_syscall_64+0x3d/0x90
     entry_SYSCALL_64_after_hwframe+0x46/0xb0
    
    Freed by task 49502:
     kasan_save_stack+0x1e/0x40
     kasan_set_track+0x21/0x30
     kasan_set_free_info+0x20/0x30
     ____kasan_slab_free+0x11d/0x1b0
     kfree+0x1ba/0x520
     mlx5e_tls_priv_tx_list_cleanup+0x2e7/0x3e0 [mlx5_core]
     mlx5e_ktls_cleanup_tx+0x38f/0x760 [mlx5_core]
     mlx5e_cleanup_nic_tx+0xa7/0x100 [mlx5_core]
     mlx5e_detach_netdev+0x1ca/0x2b0 [mlx5_core]
     mlx5e_suspend+0xdb/0x140 [mlx5_core]
     mlx5e_remove+0x89/0x190 [mlx5_core]
     auxiliary_bus_remove+0x52/0x70
     device_release_driver_internal+0x40f/0x650
     driver_detach+0xc1/0x180
     bus_remove_driver+0x125/0x2f0
     auxiliary_driver_unregister+0x16/0x50
     mlx5e_cleanup+0x26/0x30 [mlx5_core]
     cleanup+0xc/0x4e [mlx5_core]
     __x64_sys_delete_module+0x2b5/0x450
     do_syscall_64+0x3d/0x90
     entry_SYSCALL_64_after_hwframe+0x46/0xb0
    
    Fixes: e355477ed9e4 ("net/mlx5: Make mlx5_cmd_exec_cb() a safe API")
    Signed-off-by: Tariq Toukan <tariqt@xxxxxxxxxx>
    Reviewed-by: Moshe Shemesh <moshe@xxxxxxxxxx>
    Signed-off-by: Saeed Mahameed <saeedm@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20221026135153.154807-8-saeed@xxxxxxxxxx
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
index 0377392848d9..46ba4c2faad2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
@@ -2004,7 +2004,7 @@ void mlx5_cmd_init_async_ctx(struct mlx5_core_dev *dev,
 	ctx->dev = dev;
 	/* Starts at 1 to avoid doing wake_up if we are not cleaning up */
 	atomic_set(&ctx->num_inflight, 1);
-	init_waitqueue_head(&ctx->wait);
+	init_completion(&ctx->inflight_done);
 }
 EXPORT_SYMBOL(mlx5_cmd_init_async_ctx);
 
@@ -2018,8 +2018,8 @@ EXPORT_SYMBOL(mlx5_cmd_init_async_ctx);
  */
 void mlx5_cmd_cleanup_async_ctx(struct mlx5_async_ctx *ctx)
 {
-	atomic_dec(&ctx->num_inflight);
-	wait_event(ctx->wait, atomic_read(&ctx->num_inflight) == 0);
+	if (!atomic_dec_and_test(&ctx->num_inflight))
+		wait_for_completion(&ctx->inflight_done);
 }
 EXPORT_SYMBOL(mlx5_cmd_cleanup_async_ctx);
 
@@ -2032,7 +2032,7 @@ static void mlx5_cmd_exec_cb_handler(int status, void *_work)
 	status = cmd_status_err(ctx->dev, status, work->opcode, work->out);
 	work->user_callback(status, work);
 	if (atomic_dec_and_test(&ctx->num_inflight))
-		wake_up(&ctx->wait);
+		complete(&ctx->inflight_done);
 }
 
 int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,
@@ -2050,7 +2050,7 @@ int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,
 	ret = cmd_exec(ctx->dev, in, in_size, out, out_size,
 		       mlx5_cmd_exec_cb_handler, work, false);
 	if (ret && atomic_dec_and_test(&ctx->num_inflight))
-		wake_up(&ctx->wait);
+		complete(&ctx->inflight_done);
 
 	return ret;
 }
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index c32de987fa71..454dab40baf6 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -973,7 +973,7 @@ void mlx5_cmd_allowed_opcode(struct mlx5_core_dev *dev, u16 opcode);
 struct mlx5_async_ctx {
 	struct mlx5_core_dev *dev;
 	atomic_t num_inflight;
-	struct wait_queue_head wait;
+	struct completion inflight_done;
 };
 
 struct mlx5_async_work;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux