Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[Bluetooth] Export details about authentication requirements

With the Simple Pairing support, the authentication requirements are
an explicit setting during the bonding process. Track and enforce the
requirements and allow higher layers like L2CAP and RFCOMM to increase
them if needed.

This patch introduces a new IOCTL that allows to query the current
authentication requirements. It is also possible to detect Simple
Pairing support in the kernel this way.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

+68 -26
+1
fs/compat_ioctl.c
··· 2399 2399 COMPATIBLE_IOCTL(HCIGETDEVINFO) 2400 2400 COMPATIBLE_IOCTL(HCIGETCONNLIST) 2401 2401 COMPATIBLE_IOCTL(HCIGETCONNINFO) 2402 + COMPATIBLE_IOCTL(HCIGETAUTHINFO) 2402 2403 COMPATIBLE_IOCTL(HCISETRAW) 2403 2404 COMPATIBLE_IOCTL(HCISETSCAN) 2404 2405 COMPATIBLE_IOCTL(HCISETAUTH)
+14 -4
include/net/bluetooth/hci.h
··· 72 72 HCI_INQUIRY, 73 73 74 74 HCI_RAW, 75 - 76 - HCI_SECMGR 77 75 }; 78 76 79 77 /* HCI ioctl defines */ ··· 84 86 #define HCIGETDEVINFO _IOR('H', 211, int) 85 87 #define HCIGETCONNLIST _IOR('H', 212, int) 86 88 #define HCIGETCONNINFO _IOR('H', 213, int) 89 + #define HCIGETAUTHINFO _IOR('H', 215, int) 87 90 88 91 #define HCISETRAW _IOW('H', 220, int) 89 92 #define HCISETSCAN _IOW('H', 221, int) ··· 95 96 #define HCISETLINKMODE _IOW('H', 226, int) 96 97 #define HCISETACLMTU _IOW('H', 227, int) 97 98 #define HCISETSCOMTU _IOW('H', 228, int) 98 - 99 - #define HCISETSECMGR _IOW('H', 230, int) 100 99 101 100 #define HCIINQUIRY _IOR('H', 240, int) 102 101 ··· 199 202 #define HCI_LM_TRUSTED 0x0008 200 203 #define HCI_LM_RELIABLE 0x0010 201 204 #define HCI_LM_SECURE 0x0020 205 + 206 + /* Authentication types */ 207 + #define HCI_AT_NO_BONDING 0x00 208 + #define HCI_AT_NO_BONDING_MITM 0x01 209 + #define HCI_AT_DEDICATED_BONDING 0x02 210 + #define HCI_AT_DEDICATED_BONDING_MITM 0x03 211 + #define HCI_AT_GENERAL_BONDING 0x04 212 + #define HCI_AT_GENERAL_BONDING_MITM 0x05 202 213 203 214 /* ----- HCI Commands ---- */ 204 215 #define HCI_OP_INQUIRY 0x0401 ··· 1004 999 bdaddr_t bdaddr; 1005 1000 __u8 type; 1006 1001 struct hci_conn_info conn_info[0]; 1002 + }; 1003 + 1004 + struct hci_auth_info_req { 1005 + bdaddr_t bdaddr; 1006 + __u8 type; 1007 1007 }; 1008 1008 1009 1009 struct hci_inquiry_req {
+2
include/net/bluetooth/hci_core.h
··· 168 168 __u16 pkt_type; 169 169 __u16 link_policy; 170 170 __u32 link_mode; 171 + __u8 auth_type; 171 172 __u8 power_save; 172 173 unsigned long pend; 173 174 ··· 423 422 int hci_get_dev_info(void __user *arg); 424 423 int hci_get_conn_list(void __user *arg); 425 424 int hci_get_conn_info(struct hci_dev *hdev, void __user *arg); 425 + int hci_get_auth_info(struct hci_dev *hdev, void __user *arg); 426 426 int hci_inquiry(void __user *arg); 427 427 428 428 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
+34 -4
net/bluetooth/hci_conn.c
··· 379 379 { 380 380 BT_DBG("conn %p", conn); 381 381 382 + if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) { 383 + if (!(conn->auth_type & 0x01)) { 384 + conn->auth_type = HCI_AT_GENERAL_BONDING_MITM; 385 + conn->link_mode &= ~HCI_LM_AUTH; 386 + } 387 + } 388 + 382 389 if (conn->link_mode & HCI_LM_AUTH) 383 390 return 1; 384 391 385 392 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { 386 393 struct hci_cp_auth_requested cp; 387 394 cp.handle = cpu_to_le16(conn->handle); 388 - hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); 395 + hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, 396 + sizeof(cp), &cp); 389 397 } 390 398 return 0; 391 399 } ··· 405 397 BT_DBG("conn %p", conn); 406 398 407 399 if (conn->link_mode & HCI_LM_ENCRYPT) 408 - return 1; 400 + return hci_conn_auth(conn); 409 401 410 402 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) 411 403 return 0; ··· 414 406 struct hci_cp_set_conn_encrypt cp; 415 407 cp.handle = cpu_to_le16(conn->handle); 416 408 cp.encrypt = 1; 417 - hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp); 409 + hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, 410 + sizeof(cp), &cp); 418 411 } 419 412 return 0; 420 413 } ··· 429 420 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { 430 421 struct hci_cp_change_conn_link_key cp; 431 422 cp.handle = cpu_to_le16(conn->handle); 432 - hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, sizeof(cp), &cp); 423 + hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, 424 + sizeof(cp), &cp); 433 425 } 434 426 return 0; 435 427 } ··· 633 623 return -ENOENT; 634 624 635 625 return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0; 626 + } 627 + 628 + int hci_get_auth_info(struct hci_dev *hdev, void __user *arg) 629 + { 630 + struct hci_auth_info_req req; 631 + struct hci_conn *conn; 632 + 633 + if (copy_from_user(&req, arg, sizeof(req))) 634 + return -EFAULT; 635 + 636 + hci_dev_lock_bh(hdev); 637 + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &req.bdaddr); 638 + if (conn) 639 + req.type = conn->auth_type; 640 + hci_dev_unlock_bh(hdev); 641 + 642 + if (!conn) 643 + return -ENOENT; 644 + 645 + return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0; 636 646 }
+5 -13
net/bluetooth/hci_sock.c
··· 193 193 194 194 return 0; 195 195 196 - case HCISETSECMGR: 197 - if (!capable(CAP_NET_ADMIN)) 198 - return -EACCES; 199 - 200 - if (arg) 201 - set_bit(HCI_SECMGR, &hdev->flags); 202 - else 203 - clear_bit(HCI_SECMGR, &hdev->flags); 204 - 205 - return 0; 206 - 207 196 case HCIGETCONNINFO: 208 - return hci_get_conn_info(hdev, (void __user *)arg); 197 + return hci_get_conn_info(hdev, (void __user *) arg); 198 + 199 + case HCIGETAUTHINFO: 200 + return hci_get_auth_info(hdev, (void __user *) arg); 209 201 210 202 default: 211 203 if (hdev->ioctl) ··· 209 217 static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 210 218 { 211 219 struct sock *sk = sock->sk; 212 - void __user *argp = (void __user *)arg; 220 + void __user *argp = (void __user *) arg; 213 221 int err; 214 222 215 223 BT_DBG("cmd %x arg %lx", cmd, arg);
+10 -4
net/bluetooth/l2cap.c
··· 2150 2150 static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status) 2151 2151 { 2152 2152 struct l2cap_chan_list *l; 2153 - struct l2cap_conn *conn = conn = hcon->l2cap_data; 2153 + struct l2cap_conn *conn = hcon->l2cap_data; 2154 2154 struct l2cap_conn_rsp rsp; 2155 2155 struct sock *sk; 2156 2156 int result; ··· 2165 2165 read_lock(&l->lock); 2166 2166 2167 2167 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { 2168 + struct l2cap_pinfo *pi = l2cap_pi(sk); 2169 + 2168 2170 bh_lock_sock(sk); 2169 2171 2170 - if (sk->sk_state != BT_CONNECT2 || 2171 - (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) || 2172 - (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE)) { 2172 + if (sk->sk_state != BT_CONNECT2) { 2173 + bh_unlock_sock(sk); 2174 + continue; 2175 + } 2176 + 2177 + if ((pi->link_mode & (L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE)) && 2178 + !(hcon->link_mode & HCI_LM_ENCRYPT)) { 2173 2179 bh_unlock_sock(sk); 2174 2180 continue; 2175 2181 }
+2 -1
net/bluetooth/rfcomm/core.c
··· 1969 1969 list_for_each_safe(p, n, &s->dlcs) { 1970 1970 d = list_entry(p, struct rfcomm_dlc, list); 1971 1971 1972 - if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) 1972 + if ((d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) && 1973 + !(conn->link_mode & HCI_LM_ENCRYPT) && !status) 1973 1974 continue; 1974 1975 1975 1976 if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))