diff options
author | Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> | 2011-06-01 11:28:48 -0400 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-06-08 15:58:19 -0400 |
commit | 96d97a673d42408c0f960cc54d44be7629343bce (patch) | |
tree | 3f4f236d0443705ed0e7180e4d188ca9300d96d4 /net | |
parent | 24718ca5eeb6d36a4a78deb34a2d50e4017bbd4a (diff) |
Bluetooth: Verify a pin code in pin_code_reply
As we cannot relay on a userspace mgmt api implementation we should verify
if pin_code_reply in fact contains the secure pin code.
If userspace replied with unsecure pincode when secure was required we will
send pin_code_neg_reply to the controller.
Signed-off-by: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/mgmt.c | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 54154235b4a7..fcccf10f909a 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -1108,11 +1108,32 @@ unlock: | |||
1108 | return err; | 1108 | return err; |
1109 | } | 1109 | } |
1110 | 1110 | ||
1111 | static int send_pin_code_neg_reply(struct sock *sk, u16 index, | ||
1112 | struct hci_dev *hdev, struct mgmt_cp_pin_code_neg_reply *cp) | ||
1113 | { | ||
1114 | struct pending_cmd *cmd; | ||
1115 | int err; | ||
1116 | |||
1117 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, index, cp, | ||
1118 | sizeof(*cp)); | ||
1119 | if (!cmd) | ||
1120 | return -ENOMEM; | ||
1121 | |||
1122 | err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(cp->bdaddr), | ||
1123 | &cp->bdaddr); | ||
1124 | if (err < 0) | ||
1125 | mgmt_pending_remove(cmd); | ||
1126 | |||
1127 | return err; | ||
1128 | } | ||
1129 | |||
1111 | static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, | 1130 | static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, |
1112 | u16 len) | 1131 | u16 len) |
1113 | { | 1132 | { |
1114 | struct hci_dev *hdev; | 1133 | struct hci_dev *hdev; |
1134 | struct hci_conn *conn; | ||
1115 | struct mgmt_cp_pin_code_reply *cp; | 1135 | struct mgmt_cp_pin_code_reply *cp; |
1136 | struct mgmt_cp_pin_code_neg_reply ncp; | ||
1116 | struct hci_cp_pin_code_reply reply; | 1137 | struct hci_cp_pin_code_reply reply; |
1117 | struct pending_cmd *cmd; | 1138 | struct pending_cmd *cmd; |
1118 | int err; | 1139 | int err; |
@@ -1135,6 +1156,25 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1135 | goto failed; | 1156 | goto failed; |
1136 | } | 1157 | } |
1137 | 1158 | ||
1159 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); | ||
1160 | if (!conn) { | ||
1161 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENOTCONN); | ||
1162 | goto failed; | ||
1163 | } | ||
1164 | |||
1165 | if (conn->pending_sec_level == BT_SECURITY_HIGH && cp->pin_len != 16) { | ||
1166 | bacpy(&ncp.bdaddr, &cp->bdaddr); | ||
1167 | |||
1168 | BT_ERR("PIN code is not 16 bytes long"); | ||
1169 | |||
1170 | err = send_pin_code_neg_reply(sk, index, hdev, &ncp); | ||
1171 | if (err >= 0) | ||
1172 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, | ||
1173 | EINVAL); | ||
1174 | |||
1175 | goto failed; | ||
1176 | } | ||
1177 | |||
1138 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, index, data, len); | 1178 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, index, data, len); |
1139 | if (!cmd) { | 1179 | if (!cmd) { |
1140 | err = -ENOMEM; | 1180 | err = -ENOMEM; |
@@ -1161,7 +1201,6 @@ static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1161 | { | 1201 | { |
1162 | struct hci_dev *hdev; | 1202 | struct hci_dev *hdev; |
1163 | struct mgmt_cp_pin_code_neg_reply *cp; | 1203 | struct mgmt_cp_pin_code_neg_reply *cp; |
1164 | struct pending_cmd *cmd; | ||
1165 | int err; | 1204 | int err; |
1166 | 1205 | ||
1167 | BT_DBG(""); | 1206 | BT_DBG(""); |
@@ -1185,17 +1224,7 @@ static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1185 | goto failed; | 1224 | goto failed; |
1186 | } | 1225 | } |
1187 | 1226 | ||
1188 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, index, | 1227 | err = send_pin_code_neg_reply(sk, index, hdev, cp); |
1189 | data, len); | ||
1190 | if (!cmd) { | ||
1191 | err = -ENOMEM; | ||
1192 | goto failed; | ||
1193 | } | ||
1194 | |||
1195 | err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(cp->bdaddr), | ||
1196 | &cp->bdaddr); | ||
1197 | if (err < 0) | ||
1198 | mgmt_pending_remove(cmd); | ||
1199 | 1228 | ||
1200 | failed: | 1229 | failed: |
1201 | hci_dev_unlock(hdev); | 1230 | hci_dev_unlock(hdev); |