]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
Bluetooth: hci_uart: Fix NULL deref in recv callbacks when priv is uninitialized
authorAurelien DESBRIERES <aurelien@hackers.camp>
Tue, 21 Apr 2026 13:53:31 +0000 (15:53 +0200)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Wed, 6 May 2026 20:21:43 +0000 (16:21 -0400)
When a fault is injected during hci_uart line discipline setup, the
proto open() callback may fail leaving hu->priv as NULL. A subsequent
TIOCSTI ioctl can trigger the recv() callback before priv is
initialized, causing a NULL pointer dereference.

Fix all four affected HCI UART protocol drivers by adding a NULL check
on hu->priv at the start of their recv() callbacks: h4, h5, ath and
bcsp.

Reported-by: syzbot+ff30eeab8e07b37d524e@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=ff30eeab8e07b37d524e
Signed-off-by: Aurelien DESBRIERES <aurelien@hackers.camp>
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
drivers/bluetooth/hci_ath.c
drivers/bluetooth/hci_bcsp.c
drivers/bluetooth/hci_h4.c
drivers/bluetooth/hci_h5.c

index fa679ad0acdfa1a1626d756e7ee1b603a8d37cc8..8201fa7f61e848c1b56e451ad19c747a440d49b2 100644 (file)
@@ -191,6 +191,9 @@ static int ath_recv(struct hci_uart *hu, const void *data, int count)
 {
        struct ath_struct *ath = hu->priv;
 
+       if (!ath)
+               return -ENODEV;
+
        ath->rx_skb = h4_recv_buf(hu, ath->rx_skb, data, count,
                                  ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts));
        if (IS_ERR(ath->rx_skb)) {
index b386f91d8b46d59931c97c006a1410d47157e510..db56eead27cebdbd87f2c4a23fd275b7ff93725b 100644 (file)
@@ -585,6 +585,9 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count)
        if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
                return -EUNATCH;
 
+       if (!bcsp)
+               return -ENODEV;
+
        BT_DBG("hu %p count %d rx_state %d rx_count %ld",
               hu, count, bcsp->rx_state, bcsp->rx_count);
 
index a889a66a326f7a30fabe17da753aa3f23370a092..7673727074985cc27027801809701ea21371b3f2 100644 (file)
@@ -109,6 +109,9 @@ static int h4_recv(struct hci_uart *hu, const void *data, int count)
 {
        struct h4_struct *h4 = hu->priv;
 
+       if (!h4)
+               return -ENODEV;
+
        h4->rx_skb = h4_recv_buf(hu, h4->rx_skb, data, count,
                                 h4_recv_pkts, ARRAY_SIZE(h4_recv_pkts));
        if (IS_ERR(h4->rx_skb)) {
index cfdf75dc284751fc7b5d20b0dc037bfc308e6983..d3538371821254f7dfcef4e3f3436b5d3a535e3f 100644 (file)
@@ -587,6 +587,9 @@ static int h5_recv(struct hci_uart *hu, const void *data, int count)
        struct h5 *h5 = hu->priv;
        const unsigned char *ptr = data;
 
+       if (!h5)
+               return -ENODEV;
+
        BT_DBG("%s pending %zu count %d", hu->hdev->name, h5->rx_pending,
               count);