Skip to content

Commit 7a68f3c

Browse files
pvopsiff
authored andcommitted
Bluetooth: 6lowpan: fix BDADDR_LE vs ADDR_LE_DEV address type confusion
[ Upstream commit b454505 ] Bluetooth 6lowpan.c confuses BDADDR_LE and ADDR_LE_DEV address types, e.g. debugfs "connect" command takes the former, and "disconnect" and "connect" to already connected device take the latter. This is due to using same value both for l2cap_chan_connect and hci_conn_hash_lookup_le which take different dst_type values. Fix address type passed to hci_conn_hash_lookup_le(). Retain the debugfs API difference between "connect" and "disconnect" commands since it's been like this since 2015 and nobody apparently complained. Fixes: f5ad4ff ("Bluetooth: 6lowpan: Use hci_conn_hash_lookup_le() when possible") Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de> Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org> (cherry picked from commit 2a9ff4086c265939a2c6d667d4f76f2cb5139ce9) Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
1 parent fcc16c6 commit 7a68f3c

1 file changed

Lines changed: 24 additions & 4 deletions

File tree

net/bluetooth/6lowpan.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -956,10 +956,11 @@ static struct l2cap_chan *bt_6lowpan_listen(void)
956956
}
957957

958958
static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
959-
struct l2cap_conn **conn)
959+
struct l2cap_conn **conn, bool disconnect)
960960
{
961961
struct hci_conn *hcon;
962962
struct hci_dev *hdev;
963+
int le_addr_type;
963964
int n;
964965

965966
n = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
@@ -970,13 +971,32 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
970971
if (n < 7)
971972
return -EINVAL;
972973

974+
if (disconnect) {
975+
/* The "disconnect" debugfs command has used different address
976+
* type constants than "connect" since 2015. Let's retain that
977+
* for now even though it's obviously buggy...
978+
*/
979+
*addr_type += 1;
980+
}
981+
982+
switch (*addr_type) {
983+
case BDADDR_LE_PUBLIC:
984+
le_addr_type = ADDR_LE_DEV_PUBLIC;
985+
break;
986+
case BDADDR_LE_RANDOM:
987+
le_addr_type = ADDR_LE_DEV_RANDOM;
988+
break;
989+
default:
990+
return -EINVAL;
991+
}
992+
973993
/* The LE_PUBLIC address type is ignored because of BDADDR_ANY */
974994
hdev = hci_get_route(addr, BDADDR_ANY, BDADDR_LE_PUBLIC);
975995
if (!hdev)
976996
return -ENOENT;
977997

978998
hci_dev_lock(hdev);
979-
hcon = hci_conn_hash_lookup_le(hdev, addr, *addr_type);
999+
hcon = hci_conn_hash_lookup_le(hdev, addr, le_addr_type);
9801000
hci_dev_unlock(hdev);
9811001
hci_dev_put(hdev);
9821002

@@ -1103,7 +1123,7 @@ static ssize_t lowpan_control_write(struct file *fp,
11031123
buf[buf_size] = '\0';
11041124

11051125
if (memcmp(buf, "connect ", 8) == 0) {
1106-
ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn);
1126+
ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn, false);
11071127
if (ret == -EINVAL)
11081128
return ret;
11091129

@@ -1140,7 +1160,7 @@ static ssize_t lowpan_control_write(struct file *fp,
11401160
}
11411161

11421162
if (memcmp(buf, "disconnect ", 11) == 0) {
1143-
ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn);
1163+
ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn, true);
11441164
if (ret < 0)
11451165
return ret;
11461166

0 commit comments

Comments
 (0)