Commit 0f57a1e5 authored by David S. Miller's avatar David S. Miller

Merge branch 'net-rmnet-fix-interface-leak-for-rmnet-module'

Taehee Yoo says:

====================
net: rmnet: fix interface leak for rmnet module

There are two problems in rmnet module that they occur the leak of
a lower interface.
The symptom is the same, which is the leak of a lower interface.
But there are two different real problems.
This patchset is to fix these real problems.

1. Do not allow to have different two modes.
As a lower interface of rmnet, there are two modes that they are VND
and BRIDGE.
One interface can have only one mode.
But in the current rmnet, there is no code to prevent to have
two modes in one lower interface.
So, interface leak occurs.

2. Do not allow to add multiple bridge interfaces.
rmnet can have only two bridge interface.
If an additional bridge interface is tried to be attached,
rmnet should deny it.
But there is no code to do that.
So, interface leak occurs.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ccfc9df1 2fb2799a
...@@ -47,15 +47,23 @@ static int rmnet_unregister_real_device(struct net_device *real_dev) ...@@ -47,15 +47,23 @@ static int rmnet_unregister_real_device(struct net_device *real_dev)
return 0; return 0;
} }
static int rmnet_register_real_device(struct net_device *real_dev) static int rmnet_register_real_device(struct net_device *real_dev,
struct netlink_ext_ack *extack)
{ {
struct rmnet_port *port; struct rmnet_port *port;
int rc, entry; int rc, entry;
ASSERT_RTNL(); ASSERT_RTNL();
if (rmnet_is_real_dev_registered(real_dev)) if (rmnet_is_real_dev_registered(real_dev)) {
port = rmnet_get_port_rtnl(real_dev);
if (port->rmnet_mode != RMNET_EPMODE_VND) {
NL_SET_ERR_MSG_MOD(extack, "bridge device already exists");
return -EINVAL;
}
return 0; return 0;
}
port = kzalloc(sizeof(*port), GFP_KERNEL); port = kzalloc(sizeof(*port), GFP_KERNEL);
if (!port) if (!port)
...@@ -133,7 +141,7 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, ...@@ -133,7 +141,7 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]); mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]);
err = rmnet_register_real_device(real_dev); err = rmnet_register_real_device(real_dev, extack);
if (err) if (err)
goto err0; goto err0;
...@@ -422,7 +430,7 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, ...@@ -422,7 +430,7 @@ int rmnet_add_bridge(struct net_device *rmnet_dev,
} }
if (port->rmnet_mode != RMNET_EPMODE_VND) { if (port->rmnet_mode != RMNET_EPMODE_VND) {
NL_SET_ERR_MSG_MOD(extack, "bridge device already exists"); NL_SET_ERR_MSG_MOD(extack, "more than one bridge dev attached");
return -EINVAL; return -EINVAL;
} }
...@@ -433,7 +441,7 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, ...@@ -433,7 +441,7 @@ int rmnet_add_bridge(struct net_device *rmnet_dev,
return -EBUSY; return -EBUSY;
} }
err = rmnet_register_real_device(slave_dev); err = rmnet_register_real_device(slave_dev, extack);
if (err) if (err)
return -EBUSY; return -EBUSY;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment