diff options
Diffstat (limited to 'net/bluetooth')
| -rw-r--r-- | net/bluetooth/hci_core.c | 34 | ||||
| -rw-r--r-- | net/bluetooth/hci_event.c | 3 | ||||
| -rw-r--r-- | net/bluetooth/l2cap_core.c | 3 | ||||
| -rw-r--r-- | net/bluetooth/l2cap_sock.c | 5 | ||||
| -rw-r--r-- | net/bluetooth/mgmt.c | 15 | 
5 files changed, 39 insertions, 21 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index e33af63a884..edfd61addce 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -665,6 +665,11 @@ int hci_dev_open(__u16 dev)  	hci_req_lock(hdev); +	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { +		ret = -ENODEV; +		goto done; +	} +  	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {  		ret = -ERFKILL;  		goto done; @@ -1210,40 +1215,40 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)  	return NULL;  } -static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, +static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,  						u8 key_type, u8 old_key_type)  {  	/* Legacy key */  	if (key_type < 0x03) -		return 1; +		return true;  	/* Debug keys are insecure so don't store them persistently */  	if (key_type == HCI_LK_DEBUG_COMBINATION) -		return 0; +		return false;  	/* Changed combination key and there's no previous one */  	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) -		return 0; +		return false;  	/* Security mode 3 case */  	if (!conn) -		return 1; +		return true;  	/* Neither local nor remote side had no-bonding as requirement */  	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) -		return 1; +		return true;  	/* Local side had dedicated bonding as requirement */  	if (conn->auth_type == 0x02 || conn->auth_type == 0x03) -		return 1; +		return true;  	/* Remote side had dedicated bonding as requirement */  	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) -		return 1; +		return true;  	/* If none of the above criteria match, then don't store the key  	 * persistently */ -	return 0; +	return false;  }  struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) @@ -1280,7 +1285,8 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,  		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)  {  	struct link_key *key, *old_key; -	u8 old_key_type, persistent; +	u8 old_key_type; +	bool persistent;  	old_key = hci_find_link_key(hdev, bdaddr);  	if (old_key) { @@ -1323,10 +1329,8 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,  	mgmt_new_link_key(hdev, key, persistent); -	if (!persistent) { -		list_del(&key->list); -		kfree(key); -	} +	if (conn) +		conn->flush_key = !persistent;  	return 0;  } @@ -1849,6 +1853,8 @@ void hci_unregister_dev(struct hci_dev *hdev)  	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); +	set_bit(HCI_UNREGISTER, &hdev->dev_flags); +  	write_lock(&hci_dev_list_lock);  	list_del(&hdev->list);  	write_unlock(&hci_dev_list_lock); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index b37531094c4..6c065254afc 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1901,6 +1901,8 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff  	}  	if (ev->status == 0) { +		if (conn->type == ACL_LINK && conn->flush_key) +			hci_remove_link_key(hdev, &conn->dst);  		hci_proto_disconn_cfm(conn, ev->reason);  		hci_conn_del(conn);  	} @@ -2311,6 +2313,7 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk  	case HCI_OP_USER_PASSKEY_NEG_REPLY:  		hci_cc_user_passkey_neg_reply(hdev, skb); +		break;  	case HCI_OP_LE_SET_SCAN_PARAM:  		hci_cc_le_set_scan_param(hdev, skb); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index b8e17e4dac8..94552b33d52 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1308,6 +1308,7 @@ static void l2cap_monitor_timeout(struct work_struct *work)  	if (chan->retry_count >= chan->remote_max_tx) {  		l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);  		l2cap_chan_unlock(chan); +		l2cap_chan_put(chan);  		return;  	} @@ -1316,6 +1317,7 @@ static void l2cap_monitor_timeout(struct work_struct *work)  	l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);  	l2cap_chan_unlock(chan); +	l2cap_chan_put(chan);  }  static void l2cap_retrans_timeout(struct work_struct *work) @@ -1335,6 +1337,7 @@ static void l2cap_retrans_timeout(struct work_struct *work)  	l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);  	l2cap_chan_unlock(chan); +	l2cap_chan_put(chan);  }  static void l2cap_drop_acked_frames(struct l2cap_chan *chan) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index c4fe583b0af..29122ed28ea 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -82,7 +82,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)  	}  	if (la.l2_cid) -		err = l2cap_add_scid(chan, la.l2_cid); +		err = l2cap_add_scid(chan, __le16_to_cpu(la.l2_cid));  	else  		err = l2cap_add_psm(chan, &la.l2_bdaddr, la.l2_psm); @@ -123,7 +123,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al  	if (la.l2_cid && la.l2_psm)  		return -EINVAL; -	err = l2cap_chan_connect(chan, la.l2_psm, la.l2_cid, &la.l2_bdaddr); +	err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid), +				&la.l2_bdaddr);  	if (err)  		return err; diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 7fcff888713..4bb03b11112 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -2523,13 +2523,18 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,  	if (cp->val) {  		type = PAGE_SCAN_TYPE_INTERLACED; -		acp.interval = 0x0024;	/* 22.5 msec page scan interval */ + +		/* 22.5 msec page scan interval */ +		acp.interval = __constant_cpu_to_le16(0x0024);  	} else {  		type = PAGE_SCAN_TYPE_STANDARD;	/* default */ -		acp.interval = 0x0800;	/* default 1.28 sec page scan */ + +		/* default 1.28 sec page scan */ +		acp.interval = __constant_cpu_to_le16(0x0800);  	} -	acp.window = 0x0012;	/* default 11.25 msec page scan window */ +	/* default 11.25 msec page scan window */ +	acp.window = __constant_cpu_to_le16(0x0012);  	err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY, sizeof(acp),  			   &acp); @@ -2879,7 +2884,7 @@ int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status)  	return 0;  } -int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, u8 persistent) +int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, bool persistent)  {  	struct mgmt_ev_new_link_key ev; @@ -2936,7 +2941,7 @@ int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,  					  name, name_len);  	if (dev_class && memcmp(dev_class, "\0\0\0", 3) != 0) -		eir_len = eir_append_data(&ev->eir[eir_len], eir_len, +		eir_len = eir_append_data(ev->eir, eir_len,  					  EIR_CLASS_OF_DEV, dev_class, 3);  	put_unaligned_le16(eir_len, &ev->eir_len);  |