diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-11-19 15:19:39 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-11-19 16:39:06 -0500 |
commit | 2a94fe48f32ccf7321450a2cc07f2b724a444e5b (patch) | |
tree | e5a066d8f83d8822d448421019a4503f361295f9 /net/wireless | |
parent | 68eb55031da7c967d954e5f9415cd05f4abdb692 (diff) |
genetlink: make multicast groups const, prevent abuse
Register generic netlink multicast groups as an array with
the family and give them contiguous group IDs. Then instead
of passing the global group ID to the various functions that
send messages, pass the ID relative to the family - for most
families that's just 0 because the only have one group.
This avoids the list_head and ID in each group, adding a new
field for the mcast group ID offset to the family.
At the same time, this allows us to prevent abusing groups
again like the quota and dropmon code did, since we can now
check that a family only uses a group it owns.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/nl80211.c | 129 |
1 files changed, 54 insertions, 75 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f20edfd2e1f..a1eb2107317 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -47,6 +47,25 @@ static struct genl_family nl80211_fam = { .post_doit = nl80211_post_doit, }; +/* multicast groups */ +enum nl80211_multicast_groups { + NL80211_MCGRP_CONFIG, + NL80211_MCGRP_SCAN, + NL80211_MCGRP_REGULATORY, + NL80211_MCGRP_MLME, + NL80211_MCGRP_TESTMODE /* keep last - ifdef! */ +}; + +static const struct genl_multicast_group nl80211_mcgrps[] = { + [NL80211_MCGRP_CONFIG] = { .name = "config", }, + [NL80211_MCGRP_SCAN] = { .name = "scan", }, + [NL80211_MCGRP_REGULATORY] = { .name = "regulatory", }, + [NL80211_MCGRP_MLME] = { .name = "mlme", }, +#ifdef CONFIG_NL80211_TESTMODE + [NL80211_MCGRP_TESTMODE] = { .name = "testmode", } +#endif +}; + /* returns ERR_PTR values */ static struct wireless_dev * __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs) @@ -6656,10 +6675,6 @@ static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info) #ifdef CONFIG_NL80211_TESTMODE -static struct genl_multicast_group nl80211_testmode_mcgrp = { - .name = "testmode", -}; - static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -6869,7 +6884,7 @@ void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp) nla_nest_end(skb, data); genlmsg_end(skb, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), skb, 0, - nl80211_testmode_mcgrp.id, gfp); + NL80211_MCGRP_TESTMODE, gfp); } EXPORT_SYMBOL(cfg80211_testmode_event); #endif @@ -9566,21 +9581,6 @@ static const struct genl_ops nl80211_ops[] = { }, }; -static struct genl_multicast_group nl80211_mlme_mcgrp = { - .name = "mlme", -}; - -/* multicast groups */ -static struct genl_multicast_group nl80211_config_mcgrp = { - .name = "config", -}; -static struct genl_multicast_group nl80211_scan_mcgrp = { - .name = "scan", -}; -static struct genl_multicast_group nl80211_regulatory_mcgrp = { - .name = "regulatory", -}; - /* notification functions */ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) @@ -9598,7 +9598,7 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) } genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_config_mcgrp.id, GFP_KERNEL); + NL80211_MCGRP_CONFIG, GFP_KERNEL); } static int nl80211_add_scan_req(struct sk_buff *msg, @@ -9708,7 +9708,7 @@ void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, } genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_scan_mcgrp.id, GFP_KERNEL); + NL80211_MCGRP_SCAN, GFP_KERNEL); } void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, @@ -9727,7 +9727,7 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, } genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_scan_mcgrp.id, GFP_KERNEL); + NL80211_MCGRP_SCAN, GFP_KERNEL); } void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, @@ -9746,7 +9746,7 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, } genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_scan_mcgrp.id, GFP_KERNEL); + NL80211_MCGRP_SCAN, GFP_KERNEL); } void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, @@ -9765,7 +9765,7 @@ void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, } genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_scan_mcgrp.id, GFP_KERNEL); + NL80211_MCGRP_SCAN, GFP_KERNEL); } void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, @@ -9783,7 +9783,7 @@ void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, } genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_scan_mcgrp.id, GFP_KERNEL); + NL80211_MCGRP_SCAN, GFP_KERNEL); } /* @@ -9838,7 +9838,7 @@ void nl80211_send_reg_change_event(struct regulatory_request *request) rcu_read_lock(); genlmsg_multicast_allns(&nl80211_fam, msg, 0, - nl80211_regulatory_mcgrp.id, GFP_ATOMIC); + NL80211_MCGRP_REGULATORY, GFP_ATOMIC); rcu_read_unlock(); return; @@ -9874,7 +9874,7 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -9962,7 +9962,7 @@ static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10018,7 +10018,7 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10057,7 +10057,7 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10095,7 +10095,7 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, GFP_KERNEL); + NL80211_MCGRP_MLME, GFP_KERNEL); return; nla_put_failure: @@ -10129,7 +10129,7 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10170,7 +10170,7 @@ void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10209,7 +10209,7 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10262,7 +10262,7 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy, rcu_read_lock(); genlmsg_multicast_allns(&nl80211_fam, msg, 0, - nl80211_regulatory_mcgrp.id, GFP_ATOMIC); + NL80211_MCGRP_REGULATORY, GFP_ATOMIC); rcu_read_unlock(); return; @@ -10308,7 +10308,7 @@ static void nl80211_send_remain_on_chan_event( genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10363,7 +10363,7 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, } genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); } EXPORT_SYMBOL(cfg80211_new_sta); @@ -10393,7 +10393,7 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp) genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10429,7 +10429,7 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10591,7 +10591,7 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10640,7 +10640,7 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10685,7 +10685,7 @@ static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10743,7 +10743,7 @@ nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10790,7 +10790,7 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10867,7 +10867,7 @@ void cfg80211_cqm_txe_notify(struct net_device *dev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10916,7 +10916,7 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -10963,7 +10963,7 @@ void cfg80211_cqm_pktloss_notify(struct net_device *dev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -11003,7 +11003,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -11155,7 +11155,7 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; free_msg: @@ -11197,7 +11197,7 @@ void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, gfp); + NL80211_MCGRP_MLME, gfp); return; nla_put_failure: @@ -11280,7 +11280,7 @@ void cfg80211_ft_event(struct net_device *netdev, genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, GFP_KERNEL); + NL80211_MCGRP_MLME, GFP_KERNEL); } EXPORT_SYMBOL(cfg80211_ft_event); @@ -11329,32 +11329,11 @@ int nl80211_init(void) { int err; - err = genl_register_family_with_ops(&nl80211_fam, nl80211_ops); + err = genl_register_family_with_ops_groups(&nl80211_fam, nl80211_ops, + nl80211_mcgrps); if (err) return err; - err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp); - if (err) - goto err_out; - - err = genl_register_mc_group(&nl80211_fam, &nl80211_scan_mcgrp); - if (err) - goto err_out; - - err = genl_register_mc_group(&nl80211_fam, &nl80211_regulatory_mcgrp); - if (err) - goto err_out; - - err = genl_register_mc_group(&nl80211_fam, &nl80211_mlme_mcgrp); - if (err) - goto err_out; - -#ifdef CONFIG_NL80211_TESTMODE - err = genl_register_mc_group(&nl80211_fam, &nl80211_testmode_mcgrp); - if (err) - goto err_out; -#endif - err = netlink_register_notifier(&nl80211_netlink_notifier); if (err) goto err_out; |