Commit 336908f6 authored by Phoebe Buckheister's avatar Phoebe Buckheister Committed by David S. Miller

mac802154: allow only one WPAN to be up at any given time

All 802.15.4 PHY devices with drivers in tree can support only one WPAN
at any given time, yet the stack allows arbitrarily many WPAN devices to
be created and up at the same time. This cannot work with what the
hardware provides, and in the current implementation, provides an easy
DoS vector to any process on the system that may call socket() and
sendmsg().

Thus, allow only one WPAN per PHY to be up at once, just like mac80211
does for managed devices.
Signed-off-by: default avatarPhoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 01d32f6e
...@@ -36,9 +36,28 @@ ...@@ -36,9 +36,28 @@
int mac802154_slave_open(struct net_device *dev) int mac802154_slave_open(struct net_device *dev)
{ {
struct mac802154_sub_if_data *priv = netdev_priv(dev); struct mac802154_sub_if_data *priv = netdev_priv(dev);
struct mac802154_sub_if_data *subif;
struct mac802154_priv *ipriv = priv->hw; struct mac802154_priv *ipriv = priv->hw;
int res = 0; int res = 0;
ASSERT_RTNL();
if (priv->type == IEEE802154_DEV_WPAN) {
mutex_lock(&priv->hw->slaves_mtx);
list_for_each_entry(subif, &priv->hw->slaves, list) {
if (subif != priv && subif->type == priv->type &&
subif->running) {
mutex_unlock(&priv->hw->slaves_mtx);
return -EBUSY;
}
}
mutex_unlock(&priv->hw->slaves_mtx);
}
mutex_lock(&priv->hw->slaves_mtx);
priv->running = true;
mutex_unlock(&priv->hw->slaves_mtx);
if (ipriv->open_count++ == 0) { if (ipriv->open_count++ == 0) {
res = ipriv->ops->start(&ipriv->hw); res = ipriv->ops->start(&ipriv->hw);
WARN_ON(res); WARN_ON(res);
...@@ -69,8 +88,14 @@ int mac802154_slave_close(struct net_device *dev) ...@@ -69,8 +88,14 @@ int mac802154_slave_close(struct net_device *dev)
struct mac802154_sub_if_data *priv = netdev_priv(dev); struct mac802154_sub_if_data *priv = netdev_priv(dev);
struct mac802154_priv *ipriv = priv->hw; struct mac802154_priv *ipriv = priv->hw;
ASSERT_RTNL();
netif_stop_queue(dev); netif_stop_queue(dev);
mutex_lock(&priv->hw->slaves_mtx);
priv->running = false;
mutex_unlock(&priv->hw->slaves_mtx);
if (!--ipriv->open_count) if (!--ipriv->open_count)
ipriv->ops->stop(&ipriv->hw); ipriv->ops->stop(&ipriv->hw);
......
...@@ -71,6 +71,7 @@ struct mac802154_sub_if_data { ...@@ -71,6 +71,7 @@ struct mac802154_sub_if_data {
struct net_device *dev; struct net_device *dev;
int type; int type;
bool running;
spinlock_t mib_lock; spinlock_t mib_lock;
......
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