reg.c (c8c240e284b3d821011b4f680b3eaa99569b3756) | reg.c (90a53e4432b12288316efaa5f308adafb8d304b0) |
---|---|
1/* 2 * Copyright 2002-2005, Instant802 Networks, Inc. 3 * Copyright 2005-2006, Devicescape Software, Inc. 4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 5 * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com> 6 * Copyright 2013-2014 Intel Mobile Communications GmbH 7 * Copyright 2017 Intel Deutschland GmbH 8 * --- 39 unchanged lines hidden (view full) --- 48 49#include <linux/kernel.h> 50#include <linux/export.h> 51#include <linux/slab.h> 52#include <linux/list.h> 53#include <linux/ctype.h> 54#include <linux/nl80211.h> 55#include <linux/platform_device.h> | 1/* 2 * Copyright 2002-2005, Instant802 Networks, Inc. 3 * Copyright 2005-2006, Devicescape Software, Inc. 4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 5 * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com> 6 * Copyright 2013-2014 Intel Mobile Communications GmbH 7 * Copyright 2017 Intel Deutschland GmbH 8 * --- 39 unchanged lines hidden (view full) --- 48 49#include <linux/kernel.h> 50#include <linux/export.h> 51#include <linux/slab.h> 52#include <linux/list.h> 53#include <linux/ctype.h> 54#include <linux/nl80211.h> 55#include <linux/platform_device.h> |
56#include <linux/verification.h> |
|
56#include <linux/moduleparam.h> 57#include <linux/firmware.h> 58#include <net/cfg80211.h> 59#include "core.h" 60#include "reg.h" 61#include "rdev-ops.h" 62#include "nl80211.h" 63 --- 590 unchanged lines hidden (view full) --- 654 655 if (!valid_rule(data, size, rule_ptr)) 656 return false; 657 } 658 659 return true; 660} 661 | 57#include <linux/moduleparam.h> 58#include <linux/firmware.h> 59#include <net/cfg80211.h> 60#include "core.h" 61#include "reg.h" 62#include "rdev-ops.h" 63#include "nl80211.h" 64 --- 590 unchanged lines hidden (view full) --- 655 656 if (!valid_rule(data, size, rule_ptr)) 657 return false; 658 } 659 660 return true; 661} 662 |
663#ifdef CONFIG_CFG80211_REQUIRE_SIGNED_REGDB 664static struct key *builtin_regdb_keys; 665 666static void __init load_keys_from_buffer(const u8 *p, unsigned int buflen) 667{ 668 const u8 *end = p + buflen; 669 size_t plen; 670 key_ref_t key; 671 672 while (p < end) { 673 /* Each cert begins with an ASN.1 SEQUENCE tag and must be more 674 * than 256 bytes in size. 675 */ 676 if (end - p < 4) 677 goto dodgy_cert; 678 if (p[0] != 0x30 && 679 p[1] != 0x82) 680 goto dodgy_cert; 681 plen = (p[2] << 8) | p[3]; 682 plen += 4; 683 if (plen > end - p) 684 goto dodgy_cert; 685 686 key = key_create_or_update(make_key_ref(builtin_regdb_keys, 1), 687 "asymmetric", NULL, p, plen, 688 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 689 KEY_USR_VIEW | KEY_USR_READ), 690 KEY_ALLOC_NOT_IN_QUOTA | 691 KEY_ALLOC_BUILT_IN | 692 KEY_ALLOC_BYPASS_RESTRICTION); 693 if (IS_ERR(key)) { 694 pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", 695 PTR_ERR(key)); 696 } else { 697 pr_notice("Loaded X.509 cert '%s'\n", 698 key_ref_to_ptr(key)->description); 699 key_ref_put(key); 700 } 701 p += plen; 702 } 703 704 return; 705 706dodgy_cert: 707 pr_err("Problem parsing in-kernel X.509 certificate list\n"); 708} 709 710static int __init load_builtin_regdb_keys(void) 711{ 712 builtin_regdb_keys = 713 keyring_alloc(".builtin_regdb_keys", 714 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), 715 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 716 KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH), 717 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); 718 if (IS_ERR(builtin_regdb_keys)) 719 return PTR_ERR(builtin_regdb_keys); 720 721 pr_notice("Loading compiled-in X.509 certificates for regulatory database\n"); 722 723#ifdef CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS 724 load_keys_from_buffer(shipped_regdb_certs, shipped_regdb_certs_len); 725#endif 726#ifdef CFG80211_EXTRA_REGDB_KEYDIR 727 if (CONFIG_CFG80211_EXTRA_REGDB_KEYDIR[0] != '\0') 728 load_keys_from_buffer(extra_regdb_certs, extra_regdb_certs_len); 729#endif 730 731 return 0; 732} 733 734static bool regdb_has_valid_signature(const u8 *data, unsigned int size) 735{ 736 const struct firmware *sig; 737 bool result; 738 739 if (request_firmware(&sig, "regulatory.db.p7s", ®_pdev->dev)) 740 return false; 741 742 result = verify_pkcs7_signature(data, size, sig->data, sig->size, 743 builtin_regdb_keys, 744 VERIFYING_UNSPECIFIED_SIGNATURE, 745 NULL, NULL) == 0; 746 747 release_firmware(sig); 748 749 return result; 750} 751 752static void free_regdb_keyring(void) 753{ 754 key_put(builtin_regdb_keys); 755} 756#else 757static int load_builtin_regdb_keys(void) 758{ 759 return 0; 760} 761 762static bool regdb_has_valid_signature(const u8 *data, unsigned int size) 763{ 764 return true; 765} 766 767static void free_regdb_keyring(void) 768{ 769} 770#endif /* CONFIG_CFG80211_REQUIRE_SIGNED_REGDB */ 771 |
|
662static bool valid_regdb(const u8 *data, unsigned int size) 663{ 664 const struct fwdb_header *hdr = (void *)data; 665 const struct fwdb_country *country; 666 667 if (size < sizeof(*hdr)) 668 return false; 669 670 if (hdr->magic != cpu_to_be32(FWDB_MAGIC)) 671 return false; 672 673 if (hdr->version != cpu_to_be32(FWDB_VERSION)) 674 return false; 675 | 772static bool valid_regdb(const u8 *data, unsigned int size) 773{ 774 const struct fwdb_header *hdr = (void *)data; 775 const struct fwdb_country *country; 776 777 if (size < sizeof(*hdr)) 778 return false; 779 780 if (hdr->magic != cpu_to_be32(FWDB_MAGIC)) 781 return false; 782 783 if (hdr->version != cpu_to_be32(FWDB_VERSION)) 784 return false; 785 |
786 if (!regdb_has_valid_signature(data, size)) 787 return false; 788 |
|
676 country = &hdr->country[0]; 677 while ((u8 *)(country + 1) <= data + size) { 678 if (!country->coll_ptr) 679 break; 680 if (!valid_country(data, size, country)) 681 return false; 682 country++; 683 } --- 84 unchanged lines hidden (view full) --- 768 int set_error = 0; 769 bool restore = true; 770 void *db; 771 772 if (!fw) { 773 pr_info("failed to load regulatory.db\n"); 774 set_error = -ENODATA; 775 } else if (!valid_regdb(fw->data, fw->size)) { | 789 country = &hdr->country[0]; 790 while ((u8 *)(country + 1) <= data + size) { 791 if (!country->coll_ptr) 792 break; 793 if (!valid_country(data, size, country)) 794 return false; 795 country++; 796 } --- 84 unchanged lines hidden (view full) --- 881 int set_error = 0; 882 bool restore = true; 883 void *db; 884 885 if (!fw) { 886 pr_info("failed to load regulatory.db\n"); 887 set_error = -ENODATA; 888 } else if (!valid_regdb(fw->data, fw->size)) { |
776 pr_info("loaded regulatory.db is malformed\n"); | 889 pr_info("loaded regulatory.db is malformed or signature is missing/invalid\n"); |
777 set_error = -EINVAL; 778 } 779 780 rtnl_lock(); 781 if (WARN_ON(regdb && !IS_ERR(regdb))) { 782 /* just restore and free new db */ 783 } else if (set_error) { 784 regdb = ERR_PTR(set_error); --- 2745 unchanged lines hidden (view full) --- 3530 nl80211_radar_notify(rdev, chandef, event, NULL, GFP_KERNEL); 3531 } 3532} 3533 3534int __init regulatory_init(void) 3535{ 3536 int err = 0; 3537 | 890 set_error = -EINVAL; 891 } 892 893 rtnl_lock(); 894 if (WARN_ON(regdb && !IS_ERR(regdb))) { 895 /* just restore and free new db */ 896 } else if (set_error) { 897 regdb = ERR_PTR(set_error); --- 2745 unchanged lines hidden (view full) --- 3643 nl80211_radar_notify(rdev, chandef, event, NULL, GFP_KERNEL); 3644 } 3645} 3646 3647int __init regulatory_init(void) 3648{ 3649 int err = 0; 3650 |
3651 err = load_builtin_regdb_keys(); 3652 if (err) 3653 return err; 3654 |
|
3538 reg_pdev = platform_device_register_simple("regulatory", 0, NULL, 0); 3539 if (IS_ERR(reg_pdev)) 3540 return PTR_ERR(reg_pdev); 3541 3542 spin_lock_init(®_requests_lock); 3543 spin_lock_init(®_pending_beacons_lock); 3544 spin_lock_init(®_indoor_lock); 3545 --- 60 unchanged lines hidden (view full) --- 3606 3607 list_for_each_entry_safe(reg_request, tmp, ®_requests_list, list) { 3608 list_del(®_request->list); 3609 kfree(reg_request); 3610 } 3611 3612 if (!IS_ERR_OR_NULL(regdb)) 3613 kfree(regdb); | 3655 reg_pdev = platform_device_register_simple("regulatory", 0, NULL, 0); 3656 if (IS_ERR(reg_pdev)) 3657 return PTR_ERR(reg_pdev); 3658 3659 spin_lock_init(®_requests_lock); 3660 spin_lock_init(®_pending_beacons_lock); 3661 spin_lock_init(®_indoor_lock); 3662 --- 60 unchanged lines hidden (view full) --- 3723 3724 list_for_each_entry_safe(reg_request, tmp, ®_requests_list, list) { 3725 list_del(®_request->list); 3726 kfree(reg_request); 3727 } 3728 3729 if (!IS_ERR_OR_NULL(regdb)) 3730 kfree(regdb); |
3731 3732 free_regdb_keyring(); |
|
3614} | 3733} |