Skip to content

Commit 587ccf0

Browse files
TaeheeYoogregkh
authored andcommitted
net: rmnet: fix lower interface leak
commit 2a762e9 upstream. There are two types of the lower interface of rmnet that are VND and BRIDGE. Each lower interface can have only one type either VND or BRIDGE. But, there is a case, which uses both lower interface types. Due to this unexpected behavior, lower interface leak occurs. Test commands: ip link add dummy0 type dummy ip link add dummy1 type dummy ip link add rmnet0 link dummy0 type rmnet mux_id 1 ip link set dummy1 master rmnet0 ip link add rmnet1 link dummy1 type rmnet mux_id 2 ip link del rmnet0 The dummy1 was attached as BRIDGE interface of rmnet0. Then, it also was attached as VND interface of rmnet1. This is unexpected behavior and there is no code for handling this case. So that below splat occurs when the rmnet0 interface is deleted. Splat looks like: [ 53.254112][ C1] WARNING: CPU: 1 PID: 1192 at net/core/dev.c:8992 rollback_registered_many+0x986/0xcf0 [ 53.254117][ C1] Modules linked in: rmnet dummy openvswitch nsh nf_conncount nf_nat nf_conntrack nf_defrag_ipv6 nfx [ 53.254182][ C1] CPU: 1 PID: 1192 Comm: ip Not tainted 5.8.0-rc1+ #620 [ 53.254188][ C1] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 53.254192][ C1] RIP: 0010:rollback_registered_many+0x986/0xcf0 [ 53.254200][ C1] Code: 41 8b 4e cc 45 31 c0 31 d2 4c 89 ee 48 89 df e8 e0 47 ff ff 85 c0 0f 84 cd fc ff ff 0f 0b e5 [ 53.254205][ C1] RSP: 0018:ffff888050a5f2e0 EFLAGS: 00010287 [ 53.254214][ C1] RAX: ffff88805756d658 RBX: ffff88804d99c000 RCX: ffffffff8329d323 [ 53.254219][ C1] RDX: 1ffffffff0be6410 RSI: 0000000000000008 RDI: ffffffff85f32080 [ 53.254223][ C1] RBP: dffffc0000000000 R08: fffffbfff0be6411 R09: fffffbfff0be6411 [ 53.254228][ C1] R10: ffffffff85f32087 R11: 0000000000000001 R12: ffff888050a5f480 [ 53.254233][ C1] R13: ffff88804d99c0b8 R14: ffff888050a5f400 R15: ffff8880548ebe40 [ 53.254238][ C1] FS: 00007f6b86b370c0(0000) GS:ffff88806c200000(0000) knlGS:0000000000000000 [ 53.254243][ C1] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 53.254248][ C1] CR2: 0000562c62438758 CR3: 000000003f600005 CR4: 00000000000606e0 [ 53.254253][ C1] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 53.254257][ C1] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 53.254261][ C1] Call Trace: [ 53.254266][ C1] ? lockdep_hardirqs_on_prepare+0x379/0x540 [ 53.254270][ C1] ? netif_set_real_num_tx_queues+0x780/0x780 [ 53.254275][ C1] ? rmnet_unregister_real_device+0x56/0x90 [rmnet] [ 53.254279][ C1] ? __kasan_slab_free+0x126/0x150 [ 53.254283][ C1] ? kfree+0xdc/0x320 [ 53.254288][ C1] ? rmnet_unregister_real_device+0x56/0x90 [rmnet] [ 53.254293][ C1] unregister_netdevice_many.part.135+0x13/0x1b0 [ 53.254297][ C1] rtnl_delete_link+0xbc/0x100 [ 53.254301][ C1] ? rtnl_af_register+0xc0/0xc0 [ 53.254305][ C1] rtnl_dellink+0x2dc/0x840 [ 53.254309][ C1] ? find_held_lock+0x39/0x1d0 [ 53.254314][ C1] ? valid_fdb_dump_strict+0x620/0x620 [ 53.254318][ C1] ? rtnetlink_rcv_msg+0x457/0x890 [ 53.254322][ C1] ? lock_contended+0xd20/0xd20 [ 53.254326][ C1] rtnetlink_rcv_msg+0x4a8/0x890 [ ... ] [ 73.813696][ T1192] unregister_netdevice: waiting for rmnet0 to become free. Usage count = 1 Fixes: 037f9cd ("net: rmnet: use upper/lower device infrastructure") Signed-off-by: Taehee Yoo <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent d06c17f commit 587ccf0

File tree

1 file changed

+12
-7
lines changed

1 file changed

+12
-7
lines changed

drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,23 @@ static int rmnet_unregister_real_device(struct net_device *real_dev)
4747
return 0;
4848
}
4949

50-
static int rmnet_register_real_device(struct net_device *real_dev)
50+
static int rmnet_register_real_device(struct net_device *real_dev,
51+
struct netlink_ext_ack *extack)
5152
{
5253
struct rmnet_port *port;
5354
int rc, entry;
5455

5556
ASSERT_RTNL();
5657

57-
if (rmnet_is_real_dev_registered(real_dev))
58+
if (rmnet_is_real_dev_registered(real_dev)) {
59+
port = rmnet_get_port_rtnl(real_dev);
60+
if (port->rmnet_mode != RMNET_EPMODE_VND) {
61+
NL_SET_ERR_MSG_MOD(extack, "bridge device already exists");
62+
return -EINVAL;
63+
}
64+
5865
return 0;
66+
}
5967

6068
port = kzalloc(sizeof(*port), GFP_ATOMIC);
6169
if (!port)
@@ -134,7 +142,7 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
134142

135143
mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]);
136144

137-
err = rmnet_register_real_device(real_dev);
145+
err = rmnet_register_real_device(real_dev, extack);
138146
if (err)
139147
goto err0;
140148

@@ -416,13 +424,10 @@ int rmnet_add_bridge(struct net_device *rmnet_dev,
416424
if (port->nr_rmnet_devs > 1)
417425
return -EINVAL;
418426

419-
if (port->rmnet_mode != RMNET_EPMODE_VND)
420-
return -EINVAL;
421-
422427
if (rmnet_is_real_dev_registered(slave_dev))
423428
return -EBUSY;
424429

425-
err = rmnet_register_real_device(slave_dev);
430+
err = rmnet_register_real_device(slave_dev, extack);
426431
if (err)
427432
return -EBUSY;
428433

0 commit comments

Comments
 (0)