diff options
| -rw-r--r-- | net/wireless/nl80211.c | 94 |
1 files changed, 78 insertions, 16 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 304b3d568e07..241bddd0b4f1 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -1687,14 +1687,52 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
| 1687 | if (err) | 1687 | if (err) |
| 1688 | goto out_rtnl; | 1688 | goto out_rtnl; |
| 1689 | 1689 | ||
| 1690 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 1690 | err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); |
| 1691 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && | 1691 | if (err) |
| 1692 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { | ||
| 1693 | err = -EINVAL; | ||
| 1694 | goto out; | 1692 | goto out; |
| 1693 | |||
| 1694 | /* validate settings */ | ||
| 1695 | err = 0; | ||
| 1696 | |||
| 1697 | switch (dev->ieee80211_ptr->iftype) { | ||
| 1698 | case NL80211_IFTYPE_AP: | ||
| 1699 | case NL80211_IFTYPE_AP_VLAN: | ||
| 1700 | /* disallow mesh-specific things */ | ||
| 1701 | if (params.plink_action) | ||
| 1702 | err = -EINVAL; | ||
| 1703 | break; | ||
| 1704 | case NL80211_IFTYPE_STATION: | ||
| 1705 | /* disallow everything but AUTHORIZED flag */ | ||
| 1706 | if (params.plink_action) | ||
| 1707 | err = -EINVAL; | ||
| 1708 | if (params.vlan) | ||
| 1709 | err = -EINVAL; | ||
| 1710 | if (params.supported_rates) | ||
| 1711 | err = -EINVAL; | ||
| 1712 | if (params.ht_capa) | ||
| 1713 | err = -EINVAL; | ||
| 1714 | if (params.listen_interval >= 0) | ||
| 1715 | err = -EINVAL; | ||
| 1716 | if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED)) | ||
| 1717 | err = -EINVAL; | ||
| 1718 | break; | ||
| 1719 | case NL80211_IFTYPE_MESH_POINT: | ||
| 1720 | /* disallow things mesh doesn't support */ | ||
| 1721 | if (params.vlan) | ||
| 1722 | err = -EINVAL; | ||
| 1723 | if (params.ht_capa) | ||
| 1724 | err = -EINVAL; | ||
| 1725 | if (params.listen_interval >= 0) | ||
| 1726 | err = -EINVAL; | ||
| 1727 | if (params.supported_rates) | ||
| 1728 | err = -EINVAL; | ||
| 1729 | if (params.sta_flags_mask) | ||
| 1730 | err = -EINVAL; | ||
| 1731 | break; | ||
| 1732 | default: | ||
| 1733 | err = -EINVAL; | ||
| 1695 | } | 1734 | } |
| 1696 | 1735 | ||
| 1697 | err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); | ||
| 1698 | if (err) | 1736 | if (err) |
| 1699 | goto out; | 1737 | goto out; |
| 1700 | 1738 | ||
| @@ -1729,9 +1767,6 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
| 1729 | if (!info->attrs[NL80211_ATTR_MAC]) | 1767 | if (!info->attrs[NL80211_ATTR_MAC]) |
| 1730 | return -EINVAL; | 1768 | return -EINVAL; |
| 1731 | 1769 | ||
| 1732 | if (!info->attrs[NL80211_ATTR_STA_AID]) | ||
| 1733 | return -EINVAL; | ||
| 1734 | |||
| 1735 | if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]) | 1770 | if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]) |
| 1736 | return -EINVAL; | 1771 | return -EINVAL; |
| 1737 | 1772 | ||
| @@ -1746,9 +1781,11 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
| 1746 | params.listen_interval = | 1781 | params.listen_interval = |
| 1747 | nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); | 1782 | nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); |
| 1748 | 1783 | ||
| 1749 | params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); | 1784 | if (info->attrs[NL80211_ATTR_STA_AID]) { |
| 1750 | if (!params.aid || params.aid > IEEE80211_MAX_AID) | 1785 | params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); |
| 1751 | return -EINVAL; | 1786 | if (!params.aid || params.aid > IEEE80211_MAX_AID) |
| 1787 | return -EINVAL; | ||
| 1788 | } | ||
| 1752 | 1789 | ||
| 1753 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) | 1790 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) |
| 1754 | params.ht_capa = | 1791 | params.ht_capa = |
| @@ -1763,14 +1800,39 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
| 1763 | if (err) | 1800 | if (err) |
| 1764 | goto out_rtnl; | 1801 | goto out_rtnl; |
| 1765 | 1802 | ||
| 1766 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 1803 | err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); |
| 1767 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && | 1804 | if (err) |
| 1768 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { | ||
| 1769 | err = -EINVAL; | ||
| 1770 | goto out; | 1805 | goto out; |
| 1806 | |||
| 1807 | /* validate settings */ | ||
| 1808 | err = 0; | ||
| 1809 | |||
| 1810 | switch (dev->ieee80211_ptr->iftype) { | ||
| 1811 | case NL80211_IFTYPE_AP: | ||
| 1812 | case NL80211_IFTYPE_AP_VLAN: | ||
| 1813 | /* all ok but must have AID */ | ||
| 1814 | if (!params.aid) | ||
| 1815 | err = -EINVAL; | ||
| 1816 | break; | ||
| 1817 | case NL80211_IFTYPE_MESH_POINT: | ||
| 1818 | /* disallow things mesh doesn't support */ | ||
| 1819 | if (params.vlan) | ||
| 1820 | err = -EINVAL; | ||
| 1821 | if (params.aid) | ||
| 1822 | err = -EINVAL; | ||
| 1823 | if (params.ht_capa) | ||
| 1824 | err = -EINVAL; | ||
| 1825 | if (params.listen_interval >= 0) | ||
| 1826 | err = -EINVAL; | ||
| 1827 | if (params.supported_rates) | ||
| 1828 | err = -EINVAL; | ||
| 1829 | if (params.sta_flags_mask) | ||
| 1830 | err = -EINVAL; | ||
| 1831 | break; | ||
| 1832 | default: | ||
| 1833 | err = -EINVAL; | ||
| 1771 | } | 1834 | } |
| 1772 | 1835 | ||
| 1773 | err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); | ||
| 1774 | if (err) | 1836 | if (err) |
| 1775 | goto out; | 1837 | goto out; |
| 1776 | 1838 | ||
