nl80211.c (9d2bb84d54a40361c7008b33a60dc24f78724746) nl80211.c (e7a7b84e33178db4a839c5e1773247be17597c1f)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * This is the new netlink-based wireless configuration interface.
4 *
5 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
6 * Copyright 2013-2014 Intel Mobile Communications GmbH
7 * Copyright 2015-2017 Intel Deutschland GmbH
8 * Copyright (C) 2018-2022 Intel Corporation

--- 1531 unchanged lines hidden (view full) ---

1540 case NL80211_IFTYPE_MESH_POINT:
1541 break;
1542 case NL80211_IFTYPE_ADHOC:
1543 if (wdev->u.ibss.current_bss)
1544 return 0;
1545 return -ENOLINK;
1546 case NL80211_IFTYPE_STATION:
1547 case NL80211_IFTYPE_P2P_CLIENT:
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * This is the new netlink-based wireless configuration interface.
4 *
5 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
6 * Copyright 2013-2014 Intel Mobile Communications GmbH
7 * Copyright 2015-2017 Intel Deutschland GmbH
8 * Copyright (C) 2018-2022 Intel Corporation

--- 1531 unchanged lines hidden (view full) ---

1540 case NL80211_IFTYPE_MESH_POINT:
1541 break;
1542 case NL80211_IFTYPE_ADHOC:
1543 if (wdev->u.ibss.current_bss)
1544 return 0;
1545 return -ENOLINK;
1546 case NL80211_IFTYPE_STATION:
1547 case NL80211_IFTYPE_P2P_CLIENT:
1548 /* for MLO, require driver validation of the link ID */
1549 if (wdev->connected)
1550 return 0;
1551 return -ENOLINK;
1552 case NL80211_IFTYPE_UNSPECIFIED:
1553 case NL80211_IFTYPE_OCB:
1554 case NL80211_IFTYPE_MONITOR:
1555 case NL80211_IFTYPE_NAN:
1556 case NL80211_IFTYPE_P2P_DEVICE:

--- 2771 unchanged lines hidden (view full) ---

4328 if (!rdev->ops->set_noack_map)
4329 return -EOPNOTSUPP;
4330
4331 noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
4332
4333 return rdev_set_noack_map(rdev, dev, noack_map);
4334}
4335
1548 if (wdev->connected)
1549 return 0;
1550 return -ENOLINK;
1551 case NL80211_IFTYPE_UNSPECIFIED:
1552 case NL80211_IFTYPE_OCB:
1553 case NL80211_IFTYPE_MONITOR:
1554 case NL80211_IFTYPE_NAN:
1555 case NL80211_IFTYPE_P2P_DEVICE:

--- 2771 unchanged lines hidden (view full) ---

4327 if (!rdev->ops->set_noack_map)
4328 return -EOPNOTSUPP;
4329
4330 noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
4331
4332 return rdev_set_noack_map(rdev, dev, noack_map);
4333}
4334
4335static int nl80211_validate_key_link_id(struct genl_info *info,
4336 struct wireless_dev *wdev,
4337 int link_id, bool pairwise)
4338{
4339 if (pairwise) {
4340 if (link_id != -1) {
4341 GENL_SET_ERR_MSG(info,
4342 "link ID not allowed for pairwise key");
4343 return -EINVAL;
4344 }
4345
4346 return 0;
4347 }
4348
4349 if (wdev->valid_links) {
4350 if (link_id == -1) {
4351 GENL_SET_ERR_MSG(info,
4352 "link ID must for MLO group key");
4353 return -EINVAL;
4354 }
4355 if (!(wdev->valid_links & BIT(link_id))) {
4356 GENL_SET_ERR_MSG(info, "invalid link ID for MLO group key");
4357 return -EINVAL;
4358 }
4359 } else if (link_id != -1) {
4360 GENL_SET_ERR_MSG(info, "link ID not allowed for non-MLO group key");
4361 return -EINVAL;
4362 }
4363
4364 return 0;
4365}
4366
4336struct get_key_cookie {
4337 struct sk_buff *msg;
4338 int error;
4339 int idx;
4340};
4341
4342static void get_key_callback(void *c, struct key_params *params)
4343{

--- 45 unchanged lines hidden (view full) ---

4389 const u8 *mac_addr = NULL;
4390 bool pairwise;
4391 struct get_key_cookie cookie = {
4392 .error = 0,
4393 };
4394 void *hdr;
4395 struct sk_buff *msg;
4396 bool bigtk_support = false;
4367struct get_key_cookie {
4368 struct sk_buff *msg;
4369 int error;
4370 int idx;
4371};
4372
4373static void get_key_callback(void *c, struct key_params *params)
4374{

--- 45 unchanged lines hidden (view full) ---

4420 const u8 *mac_addr = NULL;
4421 bool pairwise;
4422 struct get_key_cookie cookie = {
4423 .error = 0,
4424 };
4425 void *hdr;
4426 struct sk_buff *msg;
4427 bool bigtk_support = false;
4428 int link_id = nl80211_link_id_or_invalid(info->attrs);
4429 struct wireless_dev *wdev = dev->ieee80211_ptr;
4397
4398 if (wiphy_ext_feature_isset(&rdev->wiphy,
4399 NL80211_EXT_FEATURE_BEACON_PROTECTION))
4400 bigtk_support = true;
4401
4430
4431 if (wiphy_ext_feature_isset(&rdev->wiphy,
4432 NL80211_EXT_FEATURE_BEACON_PROTECTION))
4433 bigtk_support = true;
4434
4402 if ((dev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION ||
4403 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
4435 if ((wdev->iftype == NL80211_IFTYPE_STATION ||
4436 wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
4404 wiphy_ext_feature_isset(&rdev->wiphy,
4405 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
4406 bigtk_support = true;
4407
4408 if (info->attrs[NL80211_ATTR_KEY_IDX]) {
4409 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
4410
4411 if (key_idx >= 6 && key_idx <= 7 && !bigtk_support) {

--- 35 unchanged lines hidden (view full) ---

4447
4448 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
4449 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
4450 goto nla_put_failure;
4451 if (mac_addr &&
4452 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
4453 goto nla_put_failure;
4454
4437 wiphy_ext_feature_isset(&rdev->wiphy,
4438 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
4439 bigtk_support = true;
4440
4441 if (info->attrs[NL80211_ATTR_KEY_IDX]) {
4442 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
4443
4444 if (key_idx >= 6 && key_idx <= 7 && !bigtk_support) {

--- 35 unchanged lines hidden (view full) ---

4480
4481 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
4482 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
4483 goto nla_put_failure;
4484 if (mac_addr &&
4485 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
4486 goto nla_put_failure;
4487
4455 err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie,
4456 get_key_callback);
4488 err = nl80211_validate_key_link_id(info, wdev, link_id, pairwise);
4489 if (err)
4490 goto free_msg;
4457
4491
4492 err = rdev_get_key(rdev, dev, link_id, key_idx, pairwise, mac_addr,
4493 &cookie, get_key_callback);
4494
4458 if (err)
4459 goto free_msg;
4460
4461 if (cookie.error)
4462 goto nla_put_failure;
4463
4464 genlmsg_end(msg, hdr);
4465 return genlmsg_reply(msg, info);

--- 6 unchanged lines hidden (view full) ---

4472}
4473
4474static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
4475{
4476 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4477 struct key_parse key;
4478 int err;
4479 struct net_device *dev = info->user_ptr[1];
4495 if (err)
4496 goto free_msg;
4497
4498 if (cookie.error)
4499 goto nla_put_failure;
4500
4501 genlmsg_end(msg, hdr);
4502 return genlmsg_reply(msg, info);

--- 6 unchanged lines hidden (view full) ---

4509}
4510
4511static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
4512{
4513 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4514 struct key_parse key;
4515 int err;
4516 struct net_device *dev = info->user_ptr[1];
4517 int link_id = nl80211_link_id_or_invalid(info->attrs);
4518 struct wireless_dev *wdev = dev->ieee80211_ptr;
4480
4481 err = nl80211_parse_key(info, &key);
4482 if (err)
4483 return err;
4484
4485 if (key.idx < 0)
4486 return -EINVAL;
4487
4488 /* Only support setting default key and
4489 * Extended Key ID action NL80211_KEY_SET_TX.
4490 */
4491 if (!key.def && !key.defmgmt && !key.defbeacon &&
4492 !(key.p.mode == NL80211_KEY_SET_TX))
4493 return -EINVAL;
4494
4519
4520 err = nl80211_parse_key(info, &key);
4521 if (err)
4522 return err;
4523
4524 if (key.idx < 0)
4525 return -EINVAL;
4526
4527 /* Only support setting default key and
4528 * Extended Key ID action NL80211_KEY_SET_TX.
4529 */
4530 if (!key.def && !key.defmgmt && !key.defbeacon &&
4531 !(key.p.mode == NL80211_KEY_SET_TX))
4532 return -EINVAL;
4533
4495 wdev_lock(dev->ieee80211_ptr);
4534 wdev_lock(wdev);
4496
4497 if (key.def) {
4498 if (!rdev->ops->set_default_key) {
4499 err = -EOPNOTSUPP;
4500 goto out;
4501 }
4502
4535
4536 if (key.def) {
4537 if (!rdev->ops->set_default_key) {
4538 err = -EOPNOTSUPP;
4539 goto out;
4540 }
4541
4503 err = nl80211_key_allowed(dev->ieee80211_ptr);
4542 err = nl80211_key_allowed(wdev);
4504 if (err)
4505 goto out;
4506
4543 if (err)
4544 goto out;
4545
4507 err = rdev_set_default_key(rdev, dev, key.idx,
4508 key.def_uni, key.def_multi);
4546 err = nl80211_validate_key_link_id(info, wdev, link_id, false);
4547 if (err)
4548 goto out;
4509
4549
4550 err = rdev_set_default_key(rdev, dev, link_id, key.idx,
4551 key.def_uni, key.def_multi);
4552
4510 if (err)
4511 goto out;
4512
4513#ifdef CONFIG_CFG80211_WEXT
4553 if (err)
4554 goto out;
4555
4556#ifdef CONFIG_CFG80211_WEXT
4514 dev->ieee80211_ptr->wext.default_key = key.idx;
4557 wdev->wext.default_key = key.idx;
4515#endif
4516 } else if (key.defmgmt) {
4517 if (key.def_uni || !key.def_multi) {
4518 err = -EINVAL;
4519 goto out;
4520 }
4521
4522 if (!rdev->ops->set_default_mgmt_key) {
4523 err = -EOPNOTSUPP;
4524 goto out;
4525 }
4526
4558#endif
4559 } else if (key.defmgmt) {
4560 if (key.def_uni || !key.def_multi) {
4561 err = -EINVAL;
4562 goto out;
4563 }
4564
4565 if (!rdev->ops->set_default_mgmt_key) {
4566 err = -EOPNOTSUPP;
4567 goto out;
4568 }
4569
4527 err = nl80211_key_allowed(dev->ieee80211_ptr);
4570 err = nl80211_key_allowed(wdev);
4528 if (err)
4529 goto out;
4530
4571 if (err)
4572 goto out;
4573
4531 err = rdev_set_default_mgmt_key(rdev, dev, key.idx);
4574 err = nl80211_validate_key_link_id(info, wdev, link_id, false);
4532 if (err)
4533 goto out;
4534
4575 if (err)
4576 goto out;
4577
4578 err = rdev_set_default_mgmt_key(rdev, dev, link_id, key.idx);
4579 if (err)
4580 goto out;
4581
4535#ifdef CONFIG_CFG80211_WEXT
4582#ifdef CONFIG_CFG80211_WEXT
4536 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
4583 wdev->wext.default_mgmt_key = key.idx;
4537#endif
4538 } else if (key.defbeacon) {
4539 if (key.def_uni || !key.def_multi) {
4540 err = -EINVAL;
4541 goto out;
4542 }
4543
4544 if (!rdev->ops->set_default_beacon_key) {
4545 err = -EOPNOTSUPP;
4546 goto out;
4547 }
4548
4584#endif
4585 } else if (key.defbeacon) {
4586 if (key.def_uni || !key.def_multi) {
4587 err = -EINVAL;
4588 goto out;
4589 }
4590
4591 if (!rdev->ops->set_default_beacon_key) {
4592 err = -EOPNOTSUPP;
4593 goto out;
4594 }
4595
4549 err = nl80211_key_allowed(dev->ieee80211_ptr);
4596 err = nl80211_key_allowed(wdev);
4550 if (err)
4551 goto out;
4552
4597 if (err)
4598 goto out;
4599
4553 err = rdev_set_default_beacon_key(rdev, dev, key.idx);
4600 err = nl80211_validate_key_link_id(info, wdev, link_id, false);
4554 if (err)
4555 goto out;
4601 if (err)
4602 goto out;
4603
4604 err = rdev_set_default_beacon_key(rdev, dev, link_id, key.idx);
4605 if (err)
4606 goto out;
4556 } else if (key.p.mode == NL80211_KEY_SET_TX &&
4557 wiphy_ext_feature_isset(&rdev->wiphy,
4558 NL80211_EXT_FEATURE_EXT_KEY_ID)) {
4559 u8 *mac_addr = NULL;
4560
4561 if (info->attrs[NL80211_ATTR_MAC])
4562 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4563
4564 if (!mac_addr || key.idx < 0 || key.idx > 1) {
4565 err = -EINVAL;
4566 goto out;
4567 }
4568
4607 } else if (key.p.mode == NL80211_KEY_SET_TX &&
4608 wiphy_ext_feature_isset(&rdev->wiphy,
4609 NL80211_EXT_FEATURE_EXT_KEY_ID)) {
4610 u8 *mac_addr = NULL;
4611
4612 if (info->attrs[NL80211_ATTR_MAC])
4613 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4614
4615 if (!mac_addr || key.idx < 0 || key.idx > 1) {
4616 err = -EINVAL;
4617 goto out;
4618 }
4619
4569 err = rdev_add_key(rdev, dev, key.idx,
4620 err = nl80211_validate_key_link_id(info, wdev, link_id, true);
4621 if (err)
4622 goto out;
4623
4624 err = rdev_add_key(rdev, dev, link_id, key.idx,
4570 NL80211_KEYTYPE_PAIRWISE,
4571 mac_addr, &key.p);
4572 } else {
4573 err = -EINVAL;
4574 }
4575 out:
4625 NL80211_KEYTYPE_PAIRWISE,
4626 mac_addr, &key.p);
4627 } else {
4628 err = -EINVAL;
4629 }
4630 out:
4576 wdev_unlock(dev->ieee80211_ptr);
4631 wdev_unlock(wdev);
4577
4578 return err;
4579}
4580
4581static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
4582{
4583 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4584 int err;
4585 struct net_device *dev = info->user_ptr[1];
4586 struct key_parse key;
4587 const u8 *mac_addr = NULL;
4632
4633 return err;
4634}
4635
4636static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
4637{
4638 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4639 int err;
4640 struct net_device *dev = info->user_ptr[1];
4641 struct key_parse key;
4642 const u8 *mac_addr = NULL;
4643 int link_id = nl80211_link_id_or_invalid(info->attrs);
4644 struct wireless_dev *wdev = dev->ieee80211_ptr;
4588
4589 err = nl80211_parse_key(info, &key);
4590 if (err)
4591 return err;
4592
4593 if (!key.p.key) {
4594 GENL_SET_ERR_MSG(info, "no key");
4595 return -EINVAL;

--- 25 unchanged lines hidden (view full) ---

4621
4622 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
4623 key.type == NL80211_KEYTYPE_PAIRWISE,
4624 mac_addr)) {
4625 GENL_SET_ERR_MSG(info, "key setting validation failed");
4626 return -EINVAL;
4627 }
4628
4645
4646 err = nl80211_parse_key(info, &key);
4647 if (err)
4648 return err;
4649
4650 if (!key.p.key) {
4651 GENL_SET_ERR_MSG(info, "no key");
4652 return -EINVAL;

--- 25 unchanged lines hidden (view full) ---

4678
4679 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
4680 key.type == NL80211_KEYTYPE_PAIRWISE,
4681 mac_addr)) {
4682 GENL_SET_ERR_MSG(info, "key setting validation failed");
4683 return -EINVAL;
4684 }
4685
4629 wdev_lock(dev->ieee80211_ptr);
4630 err = nl80211_key_allowed(dev->ieee80211_ptr);
4686 wdev_lock(wdev);
4687 err = nl80211_key_allowed(wdev);
4631 if (err)
4632 GENL_SET_ERR_MSG(info, "key not allowed");
4688 if (err)
4689 GENL_SET_ERR_MSG(info, "key not allowed");
4690
4691 if (!err)
4692 err = nl80211_validate_key_link_id(info, wdev, link_id,
4693 key.type == NL80211_KEYTYPE_PAIRWISE);
4694
4633 if (!err) {
4695 if (!err) {
4634 err = rdev_add_key(rdev, dev, key.idx,
4696 err = rdev_add_key(rdev, dev, link_id, key.idx,
4635 key.type == NL80211_KEYTYPE_PAIRWISE,
4636 mac_addr, &key.p);
4637 if (err)
4638 GENL_SET_ERR_MSG(info, "key addition failed");
4639 }
4697 key.type == NL80211_KEYTYPE_PAIRWISE,
4698 mac_addr, &key.p);
4699 if (err)
4700 GENL_SET_ERR_MSG(info, "key addition failed");
4701 }
4640 wdev_unlock(dev->ieee80211_ptr);
4702 wdev_unlock(wdev);
4641
4642 return err;
4643}
4644
4645static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
4646{
4647 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4648 int err;
4649 struct net_device *dev = info->user_ptr[1];
4650 u8 *mac_addr = NULL;
4651 struct key_parse key;
4703
4704 return err;
4705}
4706
4707static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
4708{
4709 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4710 int err;
4711 struct net_device *dev = info->user_ptr[1];
4712 u8 *mac_addr = NULL;
4713 struct key_parse key;
4714 int link_id = nl80211_link_id_or_invalid(info->attrs);
4715 struct wireless_dev *wdev = dev->ieee80211_ptr;
4652
4653 err = nl80211_parse_key(info, &key);
4654 if (err)
4655 return err;
4656
4657 if (info->attrs[NL80211_ATTR_MAC])
4658 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4659

--- 11 unchanged lines hidden (view full) ---

4671
4672 if (!cfg80211_valid_key_idx(rdev, key.idx,
4673 key.type == NL80211_KEYTYPE_PAIRWISE))
4674 return -EINVAL;
4675
4676 if (!rdev->ops->del_key)
4677 return -EOPNOTSUPP;
4678
4716
4717 err = nl80211_parse_key(info, &key);
4718 if (err)
4719 return err;
4720
4721 if (info->attrs[NL80211_ATTR_MAC])
4722 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4723

--- 11 unchanged lines hidden (view full) ---

4735
4736 if (!cfg80211_valid_key_idx(rdev, key.idx,
4737 key.type == NL80211_KEYTYPE_PAIRWISE))
4738 return -EINVAL;
4739
4740 if (!rdev->ops->del_key)
4741 return -EOPNOTSUPP;
4742
4679 wdev_lock(dev->ieee80211_ptr);
4680 err = nl80211_key_allowed(dev->ieee80211_ptr);
4743 wdev_lock(wdev);
4744 err = nl80211_key_allowed(wdev);
4681
4682 if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
4683 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
4684 err = -ENOENT;
4685
4686 if (!err)
4745
4746 if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
4747 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
4748 err = -ENOENT;
4749
4750 if (!err)
4687 err = rdev_del_key(rdev, dev, key.idx,
4751 err = nl80211_validate_key_link_id(info, wdev, link_id,
4752 key.type == NL80211_KEYTYPE_PAIRWISE);
4753
4754 if (!err)
4755 err = rdev_del_key(rdev, dev, link_id, key.idx,
4688 key.type == NL80211_KEYTYPE_PAIRWISE,
4689 mac_addr);
4690
4691#ifdef CONFIG_CFG80211_WEXT
4692 if (!err) {
4756 key.type == NL80211_KEYTYPE_PAIRWISE,
4757 mac_addr);
4758
4759#ifdef CONFIG_CFG80211_WEXT
4760 if (!err) {
4693 if (key.idx == dev->ieee80211_ptr->wext.default_key)
4694 dev->ieee80211_ptr->wext.default_key = -1;
4695 else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
4696 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
4761 if (key.idx == wdev->wext.default_key)
4762 wdev->wext.default_key = -1;
4763 else if (key.idx == wdev->wext.default_mgmt_key)
4764 wdev->wext.default_mgmt_key = -1;
4697 }
4698#endif
4765 }
4766#endif
4699 wdev_unlock(dev->ieee80211_ptr);
4767 wdev_unlock(wdev);
4700
4701 return err;
4702}
4703
4704/* This function returns an error or the number of nested attributes */
4705static int validate_acl_mac_addrs(struct nlattr *nl_attr)
4706{
4707 struct nlattr *attr;

--- 14981 unchanged lines hidden ---
4768
4769 return err;
4770}
4771
4772/* This function returns an error or the number of nested attributes */
4773static int validate_acl_mac_addrs(struct nlattr *nl_attr)
4774{
4775 struct nlattr *attr;

--- 14981 unchanged lines hidden ---