Skip to content

Commit 27b0420

Browse files
w1ldptrSaeed Mahameed
authored andcommitted
net/mlx5e: Lag, Fix use-after-free in fib event handler
Recent commit that modified fib route event handler to handle events according to their priority introduced use-after-free[0] in mp->mfi pointer usage. The pointer now is not just cached in order to be compared to following fib_info instances, but is also dereferenced to obtain fib_priority. However, since mlx5 lag code doesn't hold the reference to fin_info during whole mp->mfi lifetime, it could be used after fib_info instance has already been freed be kernel infrastructure code. Don't ever dereference mp->mfi pointer. Refactor it to be 'const void*' type and cache fib_info priority in dedicated integer. Group fib_info-related data into dedicated 'fib' structure that will be further extended by following patches in the series. [0]: [ 203.588029] ================================================================== [ 203.590161] BUG: KASAN: use-after-free in mlx5_lag_fib_update+0xabd/0xd60 [mlx5_core] [ 203.592386] Read of size 4 at addr ffff888144df2050 by task kworker/u20:4/138 [ 203.594766] CPU: 3 PID: 138 Comm: kworker/u20:4 Tainted: G B 5.17.0-rc7+ #6 [ 203.596751] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 [ 203.598813] Workqueue: mlx5_lag_mp mlx5_lag_fib_update [mlx5_core] [ 203.600053] Call Trace: [ 203.600608] <TASK> [ 203.601110] dump_stack_lvl+0x48/0x5e [ 203.601860] print_address_description.constprop.0+0x1f/0x160 [ 203.602950] ? mlx5_lag_fib_update+0xabd/0xd60 [mlx5_core] [ 203.604073] ? mlx5_lag_fib_update+0xabd/0xd60 [mlx5_core] [ 203.605177] kasan_report.cold+0x83/0xdf [ 203.605969] ? mlx5_lag_fib_update+0xabd/0xd60 [mlx5_core] [ 203.607102] mlx5_lag_fib_update+0xabd/0xd60 [mlx5_core] [ 203.608199] ? mlx5_lag_init_fib_work+0x1c0/0x1c0 [mlx5_core] [ 203.609382] ? read_word_at_a_time+0xe/0x20 [ 203.610463] ? strscpy+0xa0/0x2a0 [ 203.611463] process_one_work+0x722/0x1270 [ 203.612344] worker_thread+0x540/0x11e0 [ 203.613136] ? rescuer_thread+0xd50/0xd50 [ 203.613949] kthread+0x26e/0x300 [ 203.614627] ? kthread_complete_and_exit+0x20/0x20 [ 203.615542] ret_from_fork+0x1f/0x30 [ 203.616273] </TASK> [ 203.617174] Allocated by task 3746: [ 203.617874] kasan_save_stack+0x1e/0x40 [ 203.618644] __kasan_kmalloc+0x81/0xa0 [ 203.619394] fib_create_info+0xb41/0x3c50 [ 203.620213] fib_table_insert+0x190/0x1ff0 [ 203.621020] fib_magic.isra.0+0x246/0x2e0 [ 203.621803] fib_add_ifaddr+0x19f/0x670 [ 203.622563] fib_inetaddr_event+0x13f/0x270 [ 203.623377] blocking_notifier_call_chain+0xd4/0x130 [ 203.624355] __inet_insert_ifa+0x641/0xb20 [ 203.625185] inet_rtm_newaddr+0xc3d/0x16a0 [ 203.626009] rtnetlink_rcv_msg+0x309/0x880 [ 203.626826] netlink_rcv_skb+0x11d/0x340 [ 203.627626] netlink_unicast+0x4cc/0x790 [ 203.628430] netlink_sendmsg+0x762/0xc00 [ 203.629230] sock_sendmsg+0xb2/0xe0 [ 203.629955] ____sys_sendmsg+0x58a/0x770 [ 203.630756] ___sys_sendmsg+0xd8/0x160 [ 203.631523] __sys_sendmsg+0xb7/0x140 [ 203.632294] do_syscall_64+0x35/0x80 [ 203.633045] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 203.634427] Freed by task 0: [ 203.635063] kasan_save_stack+0x1e/0x40 [ 203.635844] kasan_set_track+0x21/0x30 [ 203.636618] kasan_set_free_info+0x20/0x30 [ 203.637450] __kasan_slab_free+0xfc/0x140 [ 203.638271] kfree+0x94/0x3b0 [ 203.638903] rcu_core+0x5e4/0x1990 [ 203.639640] __do_softirq+0x1ba/0x5d3 [ 203.640828] Last potentially related work creation: [ 203.641785] kasan_save_stack+0x1e/0x40 [ 203.642571] __kasan_record_aux_stack+0x9f/0xb0 [ 203.643478] call_rcu+0x88/0x9c0 [ 203.644178] fib_release_info+0x539/0x750 [ 203.644997] fib_table_delete+0x659/0xb80 [ 203.645809] fib_magic.isra.0+0x1a3/0x2e0 [ 203.646617] fib_del_ifaddr+0x93f/0x1300 [ 203.647415] fib_inetaddr_event+0x9f/0x270 [ 203.648251] blocking_notifier_call_chain+0xd4/0x130 [ 203.649225] __inet_del_ifa+0x474/0xc10 [ 203.650016] devinet_ioctl+0x781/0x17f0 [ 203.650788] inet_ioctl+0x1ad/0x290 [ 203.651533] sock_do_ioctl+0xce/0x1c0 [ 203.652315] sock_ioctl+0x27b/0x4f0 [ 203.653058] __x64_sys_ioctl+0x124/0x190 [ 203.653850] do_syscall_64+0x35/0x80 [ 203.654608] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 203.666952] The buggy address belongs to the object at ffff888144df2000 which belongs to the cache kmalloc-256 of size 256 [ 203.669250] The buggy address is located 80 bytes inside of 256-byte region [ffff888144df2000, ffff888144df2100) [ 203.671332] The buggy address belongs to the page: [ 203.672273] page:00000000bf6c9314 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x144df0 [ 203.674009] head:00000000bf6c9314 order:2 compound_mapcount:0 compound_pincount:0 [ 203.675422] flags: 0x2ffff800010200(slab|head|node=0|zone=2|lastcpupid=0x1ffff) [ 203.676819] raw: 002ffff800010200 0000000000000000 dead000000000122 ffff888100042b40 [ 203.678384] raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000 [ 203.679928] page dumped because: kasan: bad access detected [ 203.681455] Memory state around the buggy address: [ 203.682421] ffff888144df1f00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 203.683863] ffff888144df1f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 203.685310] >ffff888144df2000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 203.686701] ^ [ 203.687820] ffff888144df2080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 203.689226] ffff888144df2100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 203.690620] ================================================================== Fixes: ad11c4f ("net/mlx5e: Lag, Only handle events from highest priority multipath entry") Signed-off-by: Vlad Buslov <[email protected]> Reviewed-by: Maor Dickman <[email protected]> Reviewed-by: Leon Romanovsky <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent c4d963a commit 27b0420

File tree

2 files changed

+20
-11
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core/lag

2 files changed

+20
-11
lines changed

drivers/net/ethernet/mellanox/mlx5/core/lag/mp.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ static void mlx5_lag_fib_event_flush(struct notifier_block *nb)
100100
flush_workqueue(mp->wq);
101101
}
102102

103+
static void mlx5_lag_fib_set(struct lag_mp *mp, struct fib_info *fi)
104+
{
105+
mp->fib.mfi = fi;
106+
mp->fib.priority = fi->fib_priority;
107+
}
108+
103109
struct mlx5_fib_event_work {
104110
struct work_struct work;
105111
struct mlx5_lag *ldev;
@@ -121,13 +127,13 @@ static void mlx5_lag_fib_route_event(struct mlx5_lag *ldev,
121127
/* Handle delete event */
122128
if (event == FIB_EVENT_ENTRY_DEL) {
123129
/* stop track */
124-
if (mp->mfi == fi)
125-
mp->mfi = NULL;
130+
if (mp->fib.mfi == fi)
131+
mp->fib.mfi = NULL;
126132
return;
127133
}
128134

129135
/* Handle multipath entry with lower priority value */
130-
if (mp->mfi && mp->mfi != fi && fi->fib_priority >= mp->mfi->fib_priority)
136+
if (mp->fib.mfi && mp->fib.mfi != fi && fi->fib_priority >= mp->fib.priority)
131137
return;
132138

133139
/* Handle add/replace event */
@@ -145,7 +151,7 @@ static void mlx5_lag_fib_route_event(struct mlx5_lag *ldev,
145151
mlx5_lag_set_port_affinity(ldev, i);
146152
}
147153

148-
mp->mfi = fi;
154+
mlx5_lag_fib_set(mp, fi);
149155
return;
150156
}
151157

@@ -165,15 +171,15 @@ static void mlx5_lag_fib_route_event(struct mlx5_lag *ldev,
165171
}
166172

167173
/* First time we see multipath route */
168-
if (!mp->mfi && !__mlx5_lag_is_active(ldev)) {
174+
if (!mp->fib.mfi && !__mlx5_lag_is_active(ldev)) {
169175
struct lag_tracker tracker;
170176

171177
tracker = ldev->tracker;
172178
mlx5_activate_lag(ldev, &tracker, MLX5_LAG_FLAG_MULTIPATH, false);
173179
}
174180

175181
mlx5_lag_set_port_affinity(ldev, MLX5_LAG_NORMAL_AFFINITY);
176-
mp->mfi = fi;
182+
mlx5_lag_fib_set(mp, fi);
177183
}
178184

179185
static void mlx5_lag_fib_nexthop_event(struct mlx5_lag *ldev,
@@ -184,7 +190,7 @@ static void mlx5_lag_fib_nexthop_event(struct mlx5_lag *ldev,
184190
struct lag_mp *mp = &ldev->lag_mp;
185191

186192
/* Check the nh event is related to the route */
187-
if (!mp->mfi || mp->mfi != fi)
193+
if (!mp->fib.mfi || mp->fib.mfi != fi)
188194
return;
189195

190196
/* nh added/removed */
@@ -313,7 +319,7 @@ void mlx5_lag_mp_reset(struct mlx5_lag *ldev)
313319
/* Clear mfi, as it might become stale when a route delete event
314320
* has been missed, see mlx5_lag_fib_route_event().
315321
*/
316-
ldev->lag_mp.mfi = NULL;
322+
ldev->lag_mp.fib.mfi = NULL;
317323
}
318324

319325
int mlx5_lag_mp_init(struct mlx5_lag *ldev)
@@ -324,7 +330,7 @@ int mlx5_lag_mp_init(struct mlx5_lag *ldev)
324330
/* always clear mfi, as it might become stale when a route delete event
325331
* has been missed
326332
*/
327-
mp->mfi = NULL;
333+
mp->fib.mfi = NULL;
328334

329335
if (mp->fib_nb.notifier_call)
330336
return 0;
@@ -354,5 +360,5 @@ void mlx5_lag_mp_cleanup(struct mlx5_lag *ldev)
354360
unregister_fib_notifier(&init_net, &mp->fib_nb);
355361
destroy_workqueue(mp->wq);
356362
mp->fib_nb.notifier_call = NULL;
357-
mp->mfi = NULL;
363+
mp->fib.mfi = NULL;
358364
}

drivers/net/ethernet/mellanox/mlx5/core/lag/mp.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ enum mlx5_lag_port_affinity {
1515

1616
struct lag_mp {
1717
struct notifier_block fib_nb;
18-
struct fib_info *mfi; /* used in tracking fib events */
18+
struct {
19+
const void *mfi; /* used in tracking fib events */
20+
u32 priority;
21+
} fib;
1922
struct workqueue_struct *wq;
2023
};
2124

0 commit comments

Comments
 (0)