diff options
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r-- | net/bluetooth/mgmt.c | 60 |
1 files changed, 15 insertions, 45 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 579f7261a7fe..45b7a4e5aa42 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -908,7 +908,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
908 | struct hci_dev *hdev; | 908 | struct hci_dev *hdev; |
909 | struct mgmt_cp_load_keys *cp; | 909 | struct mgmt_cp_load_keys *cp; |
910 | u16 key_count, expected_len; | 910 | u16 key_count, expected_len; |
911 | int i, err; | 911 | int i; |
912 | 912 | ||
913 | cp = (void *) data; | 913 | cp = (void *) data; |
914 | 914 | ||
@@ -918,9 +918,9 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
918 | key_count = get_unaligned_le16(&cp->key_count); | 918 | key_count = get_unaligned_le16(&cp->key_count); |
919 | 919 | ||
920 | expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info); | 920 | expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info); |
921 | if (expected_len > len) { | 921 | if (expected_len != len) { |
922 | BT_ERR("load_keys: expected at least %u bytes, got %u bytes", | 922 | BT_ERR("load_keys: expected %u bytes, got %u bytes", |
923 | expected_len, len); | 923 | len, expected_len); |
924 | return -EINVAL; | 924 | return -EINVAL; |
925 | } | 925 | } |
926 | 926 | ||
@@ -942,36 +942,17 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
942 | else | 942 | else |
943 | clear_bit(HCI_DEBUG_KEYS, &hdev->flags); | 943 | clear_bit(HCI_DEBUG_KEYS, &hdev->flags); |
944 | 944 | ||
945 | len -= sizeof(*cp); | 945 | for (i = 0; i < key_count; i++) { |
946 | i = 0; | 946 | struct mgmt_key_info *key = &cp->keys[i]; |
947 | |||
948 | while (i < len) { | ||
949 | struct mgmt_key_info *key = (void *) cp->keys + i; | ||
950 | |||
951 | i += sizeof(*key) + key->dlen; | ||
952 | |||
953 | if (key->type == HCI_LK_SMP_LTK) { | ||
954 | struct key_master_id *id = (void *) key->data; | ||
955 | |||
956 | if (key->dlen != sizeof(struct key_master_id)) | ||
957 | continue; | ||
958 | |||
959 | hci_add_ltk(hdev, 0, &key->bdaddr, key->pin_len, | ||
960 | id->ediv, id->rand, key->val); | ||
961 | |||
962 | continue; | ||
963 | } | ||
964 | 947 | ||
965 | hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type, | 948 | hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type, |
966 | key->pin_len); | 949 | key->pin_len); |
967 | } | 950 | } |
968 | 951 | ||
969 | err = cmd_complete(sk, index, MGMT_OP_LOAD_KEYS, NULL, 0); | ||
970 | |||
971 | hci_dev_unlock_bh(hdev); | 952 | hci_dev_unlock_bh(hdev); |
972 | hci_dev_put(hdev); | 953 | hci_dev_put(hdev); |
973 | 954 | ||
974 | return err; | 955 | return 0; |
975 | } | 956 | } |
976 | 957 | ||
977 | static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len) | 958 | static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len) |
@@ -2070,28 +2051,17 @@ int mgmt_connectable(u16 index, u8 connectable) | |||
2070 | 2051 | ||
2071 | int mgmt_new_key(u16 index, struct link_key *key, u8 persistent) | 2052 | int mgmt_new_key(u16 index, struct link_key *key, u8 persistent) |
2072 | { | 2053 | { |
2073 | struct mgmt_ev_new_key *ev; | 2054 | struct mgmt_ev_new_key ev; |
2074 | int err, total; | ||
2075 | |||
2076 | total = sizeof(struct mgmt_ev_new_key) + key->dlen; | ||
2077 | ev = kzalloc(total, GFP_ATOMIC); | ||
2078 | if (!ev) | ||
2079 | return -ENOMEM; | ||
2080 | |||
2081 | bacpy(&ev->key.bdaddr, &key->bdaddr); | ||
2082 | ev->key.type = key->type; | ||
2083 | memcpy(ev->key.val, key->val, 16); | ||
2084 | ev->key.pin_len = key->pin_len; | ||
2085 | ev->key.dlen = key->dlen; | ||
2086 | ev->store_hint = persistent; | ||
2087 | |||
2088 | memcpy(ev->key.data, key->data, key->dlen); | ||
2089 | 2055 | ||
2090 | err = mgmt_event(MGMT_EV_NEW_KEY, index, ev, total, NULL); | 2056 | memset(&ev, 0, sizeof(ev)); |
2091 | 2057 | ||
2092 | kfree(ev); | 2058 | ev.store_hint = persistent; |
2059 | bacpy(&ev.key.bdaddr, &key->bdaddr); | ||
2060 | ev.key.type = key->type; | ||
2061 | memcpy(ev.key.val, key->val, 16); | ||
2062 | ev.key.pin_len = key->pin_len; | ||
2093 | 2063 | ||
2094 | return err; | 2064 | return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL); |
2095 | } | 2065 | } |
2096 | 2066 | ||
2097 | int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type) | 2067 | int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type) |