aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-06-18 11:23:43 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-06-19 11:50:24 -0400
commita97f4424fb4cddecf9b13c9b0e3f79924b624a7f (patch)
tree695ad0cfc1f5ca8a53b595e6c4f16b72170fa670 /net/wireless/nl80211.c
parent9a5e8bbc8fece7851a2a69a8676a6fd0507bc550 (diff)
cfg80211: validate station settings
When I disallowed interfering with stations on non-AP interfaces, I not only forget mesh but also managed interfaces which need this for the authorized flag. Let's actually validate everything properly. This fixes an nl80211 regression introduced by the interfering, under which wpa_supplicant -Dnl80211 could not properly connect. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c94
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, &params.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, &params.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, &params.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, &params.vlan);
1774 if (err) 1836 if (err)
1775 goto out; 1837 goto out;
1776 1838