mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 16:29:59 +00:00
bluetooth pull request for net:
- Fix race when opening vhci device - Avoid memcmp() out of bounds warning - Correctly bounds check and pad HCI_MON_NEW_INDEX name - Fix using memcmp when comparing keys - Ignore error return for hci_devcd_register() in btrtl - Always check if connection is alive before deleting - Fix a refcnt underflow problem for hci_conn -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEE7E6oRXp8w05ovYr/9JCA4xAyCykFAmUqBjIZHGx1aXoudm9u LmRlbnR6QGludGVsLmNvbQAKCRD0kIDjEDILKeVmD/95NHJd61l0JpQw9yYNjDc+ 8C2tAa4rDrbooqfhgS3PPy4SQ9X07KO9VRKaQVEjnVahnfIsbE++sptBWjMSQz94 8cRde2NJs2uUnl0Eovv9hcE/dgscXu5Lgt/fCCOyY6YwbsyFW5FmYcNUSzOLu83i 6KuPigt2n/bFC7pnB/VROmO3WusNVFX1J8unZa/MvMK5wn6DQkJeZgJlFlgJSfeg Tou4SwI8ormUsDAjV3+dVl7vZVNpyX4mv5cR6RlwHEtvcnkFIj6+ZE96M1BwOBrm zbc1OyzrXt5jXuSORlOQEAfjZUab+ygrv1tCgpVkQf+vnIiREsN/57NS6J/kmbc9 tbOqfJwYokRwjKtXsQ2bc0Jm5kvA0j/9Mrep4E3UZpTv2LwjGTaN/wXGNu1qW8+d LTgzqwmgx/PwqC4oiAFrT7guPDwoHzFqSwnvdhkdr04dH19zk7IjIm8ZrTruPDDk 3wiMOijCtx31RBlRPmfb2njostkS+ysrW1bw3vQmfs04djvcgar0MqKdauXIuBvE QMB+dyvPwCFQ8OYHQwfuwYfdHSgG7v+f35IEeflB4OISbZI4aFWkQnjvcloFpnmP m/vo+y86ORlxJiHlJypgwqxZ42nAxpGUCwxxhiMDeiqp4GzxUYcwK5RteOcDkDTb /ukSEQz/suO3Fya2kTz4mw== =SY+z -----END PGP SIGNATURE----- Merge tag 'for-net-2023-10-13' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: - Fix race when opening vhci device - Avoid memcmp() out of bounds warning - Correctly bounds check and pad HCI_MON_NEW_INDEX name - Fix using memcmp when comparing keys - Ignore error return for hci_devcd_register() in btrtl - Always check if connection is alive before deleting - Fix a refcnt underflow problem for hci_conn * tag 'for-net-2023-10-13' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: hci_sock: Correctly bounds check and pad HCI_MON_NEW_INDEX name Bluetooth: avoid memcmp() out of bounds warning Bluetooth: hci_sock: fix slab oob read in create_monitor_event Bluetooth: btrtl: Ignore error return for hci_devcd_register() Bluetooth: hci_event: Fix coding style Bluetooth: hci_event: Fix using memcmp when comparing keys Bluetooth: Fix a refcnt underflow problem for hci_conn Bluetooth: hci_sync: always check if connection is alive before deleting Bluetooth: Reject connection with the device which has same BD_ADDR Bluetooth: hci_event: Ignore NULL link key Bluetooth: ISO: Fix invalid context error Bluetooth: vhci: Fix race when opening vhci device ==================== Link: https://lore.kernel.org/r/20231014031336.1664558-1-luiz.dentz@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
2b10740ce7
7 changed files with 69 additions and 32 deletions
|
@ -962,13 +962,10 @@ static void btrtl_dmp_hdr(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
skb_put_data(skb, buf, strlen(buf));
|
||||
}
|
||||
|
||||
static int btrtl_register_devcoredump_support(struct hci_dev *hdev)
|
||||
static void btrtl_register_devcoredump_support(struct hci_dev *hdev)
|
||||
{
|
||||
int err;
|
||||
hci_devcd_register(hdev, btrtl_coredump, btrtl_dmp_hdr, NULL);
|
||||
|
||||
err = hci_devcd_register(hdev, btrtl_coredump, btrtl_dmp_hdr, NULL);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void btrtl_set_driver_name(struct hci_dev *hdev, const char *driver_name)
|
||||
|
@ -1255,8 +1252,7 @@ int btrtl_download_firmware(struct hci_dev *hdev,
|
|||
}
|
||||
|
||||
done:
|
||||
if (!err)
|
||||
err = btrtl_register_devcoredump_support(hdev);
|
||||
btrtl_register_devcoredump_support(hdev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,10 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
struct vhci_data *data = hci_get_drvdata(hdev);
|
||||
|
||||
memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
|
||||
|
||||
mutex_lock(&data->open_mutex);
|
||||
skb_queue_tail(&data->readq, skb);
|
||||
mutex_unlock(&data->open_mutex);
|
||||
|
||||
wake_up_interruptible(&data->read_wait);
|
||||
return 0;
|
||||
|
|
|
@ -56,7 +56,7 @@ struct hci_mon_new_index {
|
|||
__u8 type;
|
||||
__u8 bus;
|
||||
bdaddr_t bdaddr;
|
||||
char name[8];
|
||||
char name[8] __nonstring;
|
||||
} __packed;
|
||||
#define HCI_MON_NEW_INDEX_SIZE 16
|
||||
|
||||
|
|
|
@ -1627,6 +1627,15 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
|
|||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/* Reject outgoing connection to device with same BD ADDR against
|
||||
* CVE-2020-26555
|
||||
*/
|
||||
if (!bacmp(&hdev->bdaddr, dst)) {
|
||||
bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n",
|
||||
dst);
|
||||
return ERR_PTR(-ECONNREFUSED);
|
||||
}
|
||||
|
||||
acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
|
||||
if (!acl) {
|
||||
acl = hci_conn_add(hdev, ACL_LINK, dst, HCI_ROLE_MASTER);
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
/* Bluetooth HCI event handling. */
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <crypto/algapi.h>
|
||||
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
#include <net/bluetooth/hci_core.h>
|
||||
|
@ -3268,6 +3270,16 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
|
|||
|
||||
bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type);
|
||||
|
||||
/* Reject incoming connection from device with same BD ADDR against
|
||||
* CVE-2020-26555
|
||||
*/
|
||||
if (hdev && !bacmp(&hdev->bdaddr, &ev->bdaddr)) {
|
||||
bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n",
|
||||
&ev->bdaddr);
|
||||
hci_reject_conn(hdev, &ev->bdaddr);
|
||||
return;
|
||||
}
|
||||
|
||||
mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
|
||||
&flags);
|
||||
|
||||
|
@ -4742,6 +4754,15 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, void *data,
|
|||
if (!conn)
|
||||
goto unlock;
|
||||
|
||||
/* Ignore NULL link key against CVE-2020-26555 */
|
||||
if (!crypto_memneq(ev->link_key, ZERO_KEY, HCI_LINK_KEY_SIZE)) {
|
||||
bt_dev_dbg(hdev, "Ignore NULL link key (ZERO KEY) for %pMR",
|
||||
&ev->bdaddr);
|
||||
hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
|
||||
hci_conn_drop(conn);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
hci_conn_hold(conn);
|
||||
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
|
||||
hci_conn_drop(conn);
|
||||
|
@ -5274,8 +5295,8 @@ static u8 bredr_oob_data_present(struct hci_conn *conn)
|
|||
* available, then do not declare that OOB data is
|
||||
* present.
|
||||
*/
|
||||
if (!memcmp(data->rand256, ZERO_KEY, 16) ||
|
||||
!memcmp(data->hash256, ZERO_KEY, 16))
|
||||
if (!crypto_memneq(data->rand256, ZERO_KEY, 16) ||
|
||||
!crypto_memneq(data->hash256, ZERO_KEY, 16))
|
||||
return 0x00;
|
||||
|
||||
return 0x02;
|
||||
|
@ -5285,8 +5306,8 @@ static u8 bredr_oob_data_present(struct hci_conn *conn)
|
|||
* not supported by the hardware, then check that if
|
||||
* P-192 data values are present.
|
||||
*/
|
||||
if (!memcmp(data->rand192, ZERO_KEY, 16) ||
|
||||
!memcmp(data->hash192, ZERO_KEY, 16))
|
||||
if (!crypto_memneq(data->rand192, ZERO_KEY, 16) ||
|
||||
!crypto_memneq(data->hash192, ZERO_KEY, 16))
|
||||
return 0x00;
|
||||
|
||||
return 0x01;
|
||||
|
@ -5303,7 +5324,7 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, void *data,
|
|||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
|
||||
if (!conn)
|
||||
if (!conn || !hci_conn_ssp_enabled(conn))
|
||||
goto unlock;
|
||||
|
||||
hci_conn_hold(conn);
|
||||
|
@ -5550,7 +5571,7 @@ static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
|
|||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
|
||||
if (!conn)
|
||||
if (!conn || !hci_conn_ssp_enabled(conn))
|
||||
goto unlock;
|
||||
|
||||
/* Reset the authentication requirement to unknown */
|
||||
|
@ -7021,6 +7042,14 @@ static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data,
|
|||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static int hci_iso_term_big_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
u8 handle = PTR_UINT(data);
|
||||
|
||||
return hci_le_terminate_big_sync(hdev, handle,
|
||||
HCI_ERROR_LOCAL_HOST_TERM);
|
||||
}
|
||||
|
||||
static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
|
@ -7065,16 +7094,17 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
|
|||
rcu_read_lock();
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
if (!ev->status && !i)
|
||||
/* If no BISes have been connected for the BIG,
|
||||
* terminate. This is in case all bound connections
|
||||
* have been closed before the BIG creation
|
||||
* has completed.
|
||||
*/
|
||||
hci_le_terminate_big_sync(hdev, ev->handle,
|
||||
HCI_ERROR_LOCAL_HOST_TERM);
|
||||
hci_cmd_sync_queue(hdev, hci_iso_term_big_sync,
|
||||
UINT_PTR(ev->handle), NULL);
|
||||
|
||||
rcu_read_unlock();
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
|
|
|
@ -488,7 +488,8 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event)
|
|||
ni->type = hdev->dev_type;
|
||||
ni->bus = hdev->bus;
|
||||
bacpy(&ni->bdaddr, &hdev->bdaddr);
|
||||
memcpy(ni->name, hdev->name, 8);
|
||||
memcpy_and_pad(ni->name, sizeof(ni->name), hdev->name,
|
||||
strnlen(hdev->name, sizeof(ni->name)), '\0');
|
||||
|
||||
opcode = cpu_to_le16(HCI_MON_NEW_INDEX);
|
||||
break;
|
||||
|
|
|
@ -5369,6 +5369,7 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
|
|||
{
|
||||
int err = 0;
|
||||
u16 handle = conn->handle;
|
||||
bool disconnect = false;
|
||||
struct hci_conn *c;
|
||||
|
||||
switch (conn->state) {
|
||||
|
@ -5399,24 +5400,15 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
|
|||
hci_dev_unlock(hdev);
|
||||
return 0;
|
||||
case BT_BOUND:
|
||||
hci_dev_lock(hdev);
|
||||
hci_conn_failed(conn, reason);
|
||||
hci_dev_unlock(hdev);
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
hci_dev_lock(hdev);
|
||||
conn->state = BT_CLOSED;
|
||||
hci_disconn_cfm(conn, reason);
|
||||
hci_conn_del(conn);
|
||||
hci_dev_unlock(hdev);
|
||||
return 0;
|
||||
disconnect = true;
|
||||
break;
|
||||
}
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
/* Check if the connection hasn't been cleanup while waiting
|
||||
* commands to complete.
|
||||
*/
|
||||
/* Check if the connection has been cleaned up concurrently */
|
||||
c = hci_conn_hash_lookup_handle(hdev, handle);
|
||||
if (!c || c != conn) {
|
||||
err = 0;
|
||||
|
@ -5428,7 +5420,13 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
|
|||
* or in case of LE it was still scanning so it can be cleanup
|
||||
* safely.
|
||||
*/
|
||||
hci_conn_failed(conn, reason);
|
||||
if (disconnect) {
|
||||
conn->state = BT_CLOSED;
|
||||
hci_disconn_cfm(conn, reason);
|
||||
hci_conn_del(conn);
|
||||
} else {
|
||||
hci_conn_failed(conn, reason);
|
||||
}
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
|
|
Loading…
Reference in a new issue