bluetooth pull request for net:

- hci_sync: Protect UUID list traversal
  - RFCOMM: Fix session UAF in set_termios
  - btusb: validate Realtek vendor event length
 -----BEGIN PGP SIGNATURE-----
 
 iQJNBAABCgA3FiEE7E6oRXp8w05ovYr/9JCA4xAyCykFAmpfl74ZHGx1aXoudm9u
 LmRlbnR6QGludGVsLmNvbQAKCRD0kIDjEDILKZFrD/9Rz76Gvy+aZyGh2+UuESoJ
 vHf9SVxbrm9x2wEYE2rAoAQJuJu8ZgqDQdcYfJV83DHgNoiPrhSCRd+4jtPo685S
 8GCgzoqNU/xBiKGoFZ8ZGxp0RvmfuUmsxfB72Zv8mUY1wknyl8d+Paro2xkz2N72
 aqD20OKjhbqoe9tUwY901Oshct2IQlalaIuc5GjabGH7dGM7c4MALrj+0noBYWEJ
 XIgdcKe6cum2wnUL+ENEUi1Fg4T2u3b1L3aK8YY8Uz6Afx95vSRFLGThmNblDP4k
 X1QgPYRuRTZhFVCJdVcsJY/3gGl8pOYQAYZyAvxkJaxmKQSx7tAIMW3iuU6Bn6HX
 tzgQQ0gXHKbzMx1pEYnxzC5x5UHri4LNjoUhmkcy2J7/LT83pRw021OVyi7j6ll2
 dslrATixXFD6qQsVib+N+J07bSSuD6vSy6ys0tEUeWvxLvkocoGv8nsqQf9b+G6Y
 dbD6REScKk2U9meiEYfoIRFMzEFvZAsjieKoG/GFs9rNJjRfKsKopWxBAxg6Q2+K
 D2YYlrAc4kIbjE7iPBTMwJD98M7wywY93NQ/AR1+Ba1PNToJcGJp0XQ2LMq+nVte
 z8C8/0Yud6UVS58aJTHMN9hEuVCmyeE4OYNNfispH8QNi/vNZX5GSgYmnoqcrFaP
 uG5sKL8odHeNPAUh4xyBbQ==
 =Au1d
 -----END PGP SIGNATURE-----

Merge tag 'for-net-2026-07-21' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth

Luiz Augusto von Dentz says:

====================
bluetooth pull request for net:

 - hci_sync: Protect UUID list traversal
 - RFCOMM: Fix session UAF in set_termios
 - btusb: validate Realtek vendor event length

* tag 'for-net-2026-07-21' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth:
  Bluetooth: btusb: validate Realtek vendor event length
  Bluetooth: RFCOMM: Fix session UAF in set_termios
  Bluetooth: hci_sync: Protect UUID list traversal
====================

Link: https://patch.msgid.link/20260721160240.884274-1-luiz.dentz@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-07-22 10:18:58 -07:00
commit 9a67bbfe48
5 changed files with 37 additions and 7 deletions

View File

@ -2782,7 +2782,9 @@ static int btusb_setup_realtek(struct hci_dev *hdev)
static int btusb_recv_event_realtek(struct hci_dev *hdev, struct sk_buff *skb)
{
if (skb->data[0] == HCI_VENDOR_PKT && skb->data[2] == RTK_SUB_EVENT_CODE_COREDUMP) {
if (skb->len >= HCI_EVENT_HDR_SIZE + 1 &&
skb->data[0] == HCI_VENDOR_PKT &&
skb->data[2] == RTK_SUB_EVENT_CODE_COREDUMP) {
struct rtk_dev_coredump_hdr hdr = {
.code = RTK_DEVCOREDUMP_CODE_MEMDUMP,
};

View File

@ -226,6 +226,9 @@ int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
u8 bit_rate, u8 data_bits, u8 stop_bits,
u8 parity, u8 flow_ctrl_settings,
u8 xon_char, u8 xoff_char, u16 param_mask);
int rfcomm_dlc_send_rpn(struct rfcomm_dlc *d, u8 bit_rate, u8 data_bits,
u8 stop_bits, u8 parity, u8 flow_ctrl_settings,
u8 xon_char, u8 xoff_char, u16 param_mask);
/* ---- RFCOMM DLCs (channels) ---- */
struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio);

View File

@ -929,12 +929,16 @@ int hci_update_eir_sync(struct hci_dev *hdev)
memset(&cp, 0, sizeof(cp));
hci_dev_lock(hdev);
eir_create(hdev, cp.data);
if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0)
if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0) {
hci_dev_unlock(hdev);
return 0;
}
memcpy(hdev->eir, cp.data, sizeof(cp.data));
hci_dev_unlock(hdev);
return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp,
HCI_CMD_TIMEOUT);
@ -966,6 +970,7 @@ int hci_update_class_sync(struct hci_dev *hdev)
if (hci_dev_test_flag(hdev, HCI_SERVICE_CACHE))
return 0;
hci_dev_lock(hdev);
cod[0] = hdev->minor_class;
cod[1] = hdev->major_class;
cod[2] = get_service_classes(hdev);
@ -973,8 +978,12 @@ int hci_update_class_sync(struct hci_dev *hdev)
if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE))
cod[1] |= 0x20;
if (memcmp(cod, hdev->dev_class, 3) == 0)
if (memcmp(cod, hdev->dev_class, 3) == 0) {
hci_dev_unlock(hdev);
return 0;
}
hci_dev_unlock(hdev);
return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_CLASS_OF_DEV,
sizeof(cod), cod, HCI_CMD_TIMEOUT);

View File

@ -1028,6 +1028,23 @@ int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
return rfcomm_send_frame(s, buf, ptr - buf);
}
int rfcomm_dlc_send_rpn(struct rfcomm_dlc *d, u8 bit_rate, u8 data_bits,
u8 stop_bits, u8 parity, u8 flow_ctrl_settings,
u8 xon_char, u8 xoff_char, u16 param_mask)
{
int err = -ENOTCONN;
rfcomm_lock();
if (d->session)
err = rfcomm_send_rpn(d->session, 1, d->dlci, bit_rate,
data_bits, stop_bits, parity,
flow_ctrl_settings, xon_char, xoff_char,
param_mask);
rfcomm_unlock();
return err;
}
static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status)
{
struct rfcomm_hdr *hdr;

View File

@ -858,7 +858,7 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty,
BT_DBG("tty %p termios %p", tty, old);
if (!dev || !dev->dlc || !dev->dlc->session)
if (!dev || !dev->dlc)
return;
/* Handle turning off CRTSCTS */
@ -979,9 +979,8 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty,
}
if (changes)
rfcomm_send_rpn(dev->dlc->session, 1, dev->dlc->dlci, baud,
data_bits, stop_bits, parity,
RFCOMM_RPN_FLOW_NONE, x_on, x_off, changes);
rfcomm_dlc_send_rpn(dev->dlc, baud, data_bits, stop_bits, parity,
RFCOMM_RPN_FLOW_NONE, x_on, x_off, changes);
}
static void rfcomm_tty_throttle(struct tty_struct *tty)