Skip to content

Commit 2ac5415

Browse files
zhuyjrleon
authored andcommitted
RDMA/rxe: Remove the direct link to net_device
The similar patch in siw is in the link: https://git.kernel.org/rdma/rdma/c/16b87037b48889 This problem also occurred in RXE. The following analyze this problem. In the following Call Traces: " BUG: KASAN: slab-use-after-free in dev_get_flags+0x188/0x1d0 net/core/dev.c:8782 Read of size 4 at addr ffff8880554640b0 by task kworker/1:4/5295 CPU: 1 UID: 0 PID: 5295 Comm: kworker/1:4 Not tainted 6.12.0-rc3-syzkaller-00399-g9197b73fd7bb #0 Hardware name: Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 Workqueue: infiniband ib_cache_event_task Call Trace: <TASK> __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:377 [inline] print_report+0x169/0x550 mm/kasan/report.c:488 kasan_report+0x143/0x180 mm/kasan/report.c:601 dev_get_flags+0x188/0x1d0 net/core/dev.c:8782 rxe_query_port+0x12d/0x260 drivers/infiniband/sw/rxe/rxe_verbs.c:60 __ib_query_port drivers/infiniband/core/device.c:2111 [inline] ib_query_port+0x168/0x7d0 drivers/infiniband/core/device.c:2143 ib_cache_update+0x1a9/0xb80 drivers/infiniband/core/cache.c:1494 ib_cache_event_task+0xf3/0x1e0 drivers/infiniband/core/cache.c:1568 process_one_work kernel/workqueue.c:3229 [inline] process_scheduled_works+0xa65/0x1850 kernel/workqueue.c:3310 worker_thread+0x870/0xd30 kernel/workqueue.c:3391 kthread+0x2f2/0x390 kernel/kthread.c:389 ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 </TASK> " 1). In the link [1], " infiniband syz2: set down " This means that on 839.350575, the event ib_cache_event_task was sent andi queued in ib_wq. 2). In the link [1], " team0 (unregistering): Port device team_slave_0 removed " It indicates that before 843.251853, the net device should be freed. 3). In the link [1], " BUG: KASAN: slab-use-after-free in dev_get_flags+0x188/0x1d0 " This means that on 850.559070, this slab-use-after-free problem occurred. In all, on 839.350575, the event ib_cache_event_task was sent and queued in ib_wq, before 843.251853, the net device veth was freed. on 850.559070, this event was executed, and the mentioned freed net device was called. Thus, the above call trace occurred. [1] https://syzkaller.appspot.com/x/log.txt?x=12e7025f980000 Reported-by: syzbot+4b87489410b4efd181bf@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=4b87489410b4efd181bf Fixes: 8700e3e ("Soft RoCE driver") Signed-off-by: Zhu Yanjun <yanjun.zhu@linux.dev> Link: https://patch.msgid.link/20241220222325.2487767-1-yanjun.zhu@linux.dev Signed-off-by: Leon Romanovsky <leon@kernel.org>
1 parent e3debdd commit 2ac5415

File tree

6 files changed

+90
-19
lines changed

6 files changed

+90
-19
lines changed

drivers/infiniband/sw/rxe/rxe.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ void rxe_dealloc(struct ib_device *ib_dev)
4040
/* initialize rxe device parameters */
4141
static void rxe_init_device_param(struct rxe_dev *rxe)
4242
{
43+
struct net_device *ndev;
44+
4345
rxe->max_inline_data = RXE_MAX_INLINE_DATA;
4446

4547
rxe->attr.vendor_id = RXE_VENDOR_ID;
@@ -71,8 +73,15 @@ static void rxe_init_device_param(struct rxe_dev *rxe)
7173
rxe->attr.max_fast_reg_page_list_len = RXE_MAX_FMR_PAGE_LIST_LEN;
7274
rxe->attr.max_pkeys = RXE_MAX_PKEYS;
7375
rxe->attr.local_ca_ack_delay = RXE_LOCAL_CA_ACK_DELAY;
76+
77+
ndev = rxe_ib_device_get_netdev(&rxe->ib_dev);
78+
if (!ndev)
79+
return;
80+
7481
addrconf_addr_eui48((unsigned char *)&rxe->attr.sys_image_guid,
75-
rxe->ndev->dev_addr);
82+
ndev->dev_addr);
83+
84+
dev_put(ndev);
7685

7786
rxe->max_ucontext = RXE_MAX_UCONTEXT;
7887
}
@@ -109,10 +118,15 @@ static void rxe_init_port_param(struct rxe_port *port)
109118
static void rxe_init_ports(struct rxe_dev *rxe)
110119
{
111120
struct rxe_port *port = &rxe->port;
121+
struct net_device *ndev;
112122

113123
rxe_init_port_param(port);
124+
ndev = rxe_ib_device_get_netdev(&rxe->ib_dev);
125+
if (!ndev)
126+
return;
114127
addrconf_addr_eui48((unsigned char *)&port->port_guid,
115-
rxe->ndev->dev_addr);
128+
ndev->dev_addr);
129+
dev_put(ndev);
116130
spin_lock_init(&port->port_lock);
117131
}
118132

@@ -167,12 +181,13 @@ void rxe_set_mtu(struct rxe_dev *rxe, unsigned int ndev_mtu)
167181
/* called by ifc layer to create new rxe device.
168182
* The caller should allocate memory for rxe by calling ib_alloc_device.
169183
*/
170-
int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name)
184+
int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name,
185+
struct net_device *ndev)
171186
{
172187
rxe_init(rxe);
173188
rxe_set_mtu(rxe, mtu);
174189

175-
return rxe_register_device(rxe, ibdev_name);
190+
return rxe_register_device(rxe, ibdev_name, ndev);
176191
}
177192

178193
static int rxe_newlink(const char *ibdev_name, struct net_device *ndev)

drivers/infiniband/sw/rxe/rxe.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ enum resp_states {
139139

140140
void rxe_set_mtu(struct rxe_dev *rxe, unsigned int dev_mtu);
141141

142-
int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name);
142+
int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name,
143+
struct net_device *ndev);
143144

144145
void rxe_rcv(struct sk_buff *skb);
145146

drivers/infiniband/sw/rxe/rxe_mcast.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,19 @@
3131
static int rxe_mcast_add(struct rxe_dev *rxe, union ib_gid *mgid)
3232
{
3333
unsigned char ll_addr[ETH_ALEN];
34+
struct net_device *ndev;
35+
int ret;
36+
37+
ndev = rxe_ib_device_get_netdev(&rxe->ib_dev);
38+
if (!ndev)
39+
return -ENODEV;
3440

3541
ipv6_eth_mc_map((struct in6_addr *)mgid->raw, ll_addr);
3642

37-
return dev_mc_add(rxe->ndev, ll_addr);
43+
ret = dev_mc_add(ndev, ll_addr);
44+
dev_put(ndev);
45+
46+
return ret;
3847
}
3948

4049
/**
@@ -47,10 +56,19 @@ static int rxe_mcast_add(struct rxe_dev *rxe, union ib_gid *mgid)
4756
static int rxe_mcast_del(struct rxe_dev *rxe, union ib_gid *mgid)
4857
{
4958
unsigned char ll_addr[ETH_ALEN];
59+
struct net_device *ndev;
60+
int ret;
61+
62+
ndev = rxe_ib_device_get_netdev(&rxe->ib_dev);
63+
if (!ndev)
64+
return -ENODEV;
5065

5166
ipv6_eth_mc_map((struct in6_addr *)mgid->raw, ll_addr);
5267

53-
return dev_mc_del(rxe->ndev, ll_addr);
68+
ret = dev_mc_del(ndev, ll_addr);
69+
dev_put(ndev);
70+
71+
return ret;
5472
}
5573

5674
/**

drivers/infiniband/sw/rxe/rxe_net.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,16 @@ struct sk_buff *rxe_init_packet(struct rxe_dev *rxe, struct rxe_av *av,
524524
*/
525525
const char *rxe_parent_name(struct rxe_dev *rxe, unsigned int port_num)
526526
{
527-
return rxe->ndev->name;
527+
struct net_device *ndev;
528+
char *ndev_name;
529+
530+
ndev = rxe_ib_device_get_netdev(&rxe->ib_dev);
531+
if (!ndev)
532+
return NULL;
533+
ndev_name = ndev->name;
534+
dev_put(ndev);
535+
536+
return ndev_name;
528537
}
529538

530539
int rxe_net_add(const char *ibdev_name, struct net_device *ndev)
@@ -536,10 +545,9 @@ int rxe_net_add(const char *ibdev_name, struct net_device *ndev)
536545
if (!rxe)
537546
return -ENOMEM;
538547

539-
rxe->ndev = ndev;
540548
ib_mark_name_assigned_by_user(&rxe->ib_dev);
541549

542-
err = rxe_add(rxe, ndev->mtu, ibdev_name);
550+
err = rxe_add(rxe, ndev->mtu, ibdev_name, ndev);
543551
if (err) {
544552
ib_dealloc_device(&rxe->ib_dev);
545553
return err;
@@ -587,10 +595,18 @@ void rxe_port_down(struct rxe_dev *rxe)
587595

588596
void rxe_set_port_state(struct rxe_dev *rxe)
589597
{
590-
if (netif_running(rxe->ndev) && netif_carrier_ok(rxe->ndev))
598+
struct net_device *ndev;
599+
600+
ndev = rxe_ib_device_get_netdev(&rxe->ib_dev);
601+
if (!ndev)
602+
return;
603+
604+
if (netif_running(ndev) && netif_carrier_ok(ndev))
591605
rxe_port_up(rxe);
592606
else
593607
rxe_port_down(rxe);
608+
609+
dev_put(ndev);
594610
}
595611

596612
static int rxe_notify(struct notifier_block *not_blk,

drivers/infiniband/sw/rxe/rxe_verbs.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ static int rxe_query_port(struct ib_device *ibdev,
4141
u32 port_num, struct ib_port_attr *attr)
4242
{
4343
struct rxe_dev *rxe = to_rdev(ibdev);
44+
struct net_device *ndev;
4445
int err, ret;
4546

4647
if (port_num != 1) {
@@ -49,6 +50,12 @@ static int rxe_query_port(struct ib_device *ibdev,
4950
goto err_out;
5051
}
5152

53+
ndev = rxe_ib_device_get_netdev(ibdev);
54+
if (!ndev) {
55+
err = -ENODEV;
56+
goto err_out;
57+
}
58+
5259
memcpy(attr, &rxe->port.attr, sizeof(*attr));
5360

5461
mutex_lock(&rxe->usdev_lock);
@@ -57,13 +64,14 @@ static int rxe_query_port(struct ib_device *ibdev,
5764

5865
if (attr->state == IB_PORT_ACTIVE)
5966
attr->phys_state = IB_PORT_PHYS_STATE_LINK_UP;
60-
else if (dev_get_flags(rxe->ndev) & IFF_UP)
67+
else if (dev_get_flags(ndev) & IFF_UP)
6168
attr->phys_state = IB_PORT_PHYS_STATE_POLLING;
6269
else
6370
attr->phys_state = IB_PORT_PHYS_STATE_DISABLED;
6471

6572
mutex_unlock(&rxe->usdev_lock);
6673

74+
dev_put(ndev);
6775
return ret;
6876

6977
err_out:
@@ -1425,9 +1433,16 @@ static const struct attribute_group rxe_attr_group = {
14251433
static int rxe_enable_driver(struct ib_device *ib_dev)
14261434
{
14271435
struct rxe_dev *rxe = container_of(ib_dev, struct rxe_dev, ib_dev);
1436+
struct net_device *ndev;
1437+
1438+
ndev = rxe_ib_device_get_netdev(ib_dev);
1439+
if (!ndev)
1440+
return -ENODEV;
14281441

14291442
rxe_set_port_state(rxe);
1430-
dev_info(&rxe->ib_dev.dev, "added %s\n", netdev_name(rxe->ndev));
1443+
dev_info(&rxe->ib_dev.dev, "added %s\n", netdev_name(ndev));
1444+
1445+
dev_put(ndev);
14311446
return 0;
14321447
}
14331448

@@ -1495,7 +1510,8 @@ static const struct ib_device_ops rxe_dev_ops = {
14951510
INIT_RDMA_OBJ_SIZE(ib_mw, rxe_mw, ibmw),
14961511
};
14971512

1498-
int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name)
1513+
int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name,
1514+
struct net_device *ndev)
14991515
{
15001516
int err;
15011517
struct ib_device *dev = &rxe->ib_dev;
@@ -1507,13 +1523,13 @@ int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name)
15071523
dev->num_comp_vectors = num_possible_cpus();
15081524
dev->local_dma_lkey = 0;
15091525
addrconf_addr_eui48((unsigned char *)&dev->node_guid,
1510-
rxe->ndev->dev_addr);
1526+
ndev->dev_addr);
15111527

15121528
dev->uverbs_cmd_mask |= BIT_ULL(IB_USER_VERBS_CMD_POST_SEND) |
15131529
BIT_ULL(IB_USER_VERBS_CMD_REQ_NOTIFY_CQ);
15141530

15151531
ib_set_device_ops(dev, &rxe_dev_ops);
1516-
err = ib_device_set_netdev(&rxe->ib_dev, rxe->ndev, 1);
1532+
err = ib_device_set_netdev(&rxe->ib_dev, ndev, 1);
15171533
if (err)
15181534
return err;
15191535

drivers/infiniband/sw/rxe/rxe_verbs.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,15 +370,14 @@ struct rxe_port {
370370
u32 qp_gsi_index;
371371
};
372372

373+
#define RXE_PORT 1
373374
struct rxe_dev {
374375
struct ib_device ib_dev;
375376
struct ib_device_attr attr;
376377
int max_ucontext;
377378
int max_inline_data;
378379
struct mutex usdev_lock;
379380

380-
struct net_device *ndev;
381-
382381
struct rxe_pool uc_pool;
383382
struct rxe_pool pd_pool;
384383
struct rxe_pool ah_pool;
@@ -406,6 +405,11 @@ struct rxe_dev {
406405
struct crypto_shash *tfm;
407406
};
408407

408+
static inline struct net_device *rxe_ib_device_get_netdev(struct ib_device *dev)
409+
{
410+
return ib_device_get_netdev(dev, RXE_PORT);
411+
}
412+
409413
static inline void rxe_counter_inc(struct rxe_dev *rxe, enum rxe_counters index)
410414
{
411415
atomic64_inc(&rxe->stats_counters[index]);
@@ -471,6 +475,7 @@ static inline struct rxe_pd *rxe_mw_pd(struct rxe_mw *mw)
471475
return to_rpd(mw->ibmw.pd);
472476
}
473477

474-
int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name);
478+
int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name,
479+
struct net_device *ndev);
475480

476481
#endif /* RXE_VERBS_H */

0 commit comments

Comments
 (0)