Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Bluetooth: fix corruption in h4_recv_buf() after cleanup

A different structure is stored in drvdata for the drivers which used
that duplicate function, but h4_recv_buf() assumes drvdata is always an
hci_uart structure.

Consequently, alignment and padding are now randomly corrupted for
btmtkuart, btnxpuart, and bpa10x in h4_recv_buf(), causing erratic
breakage.

Fix this by making the hci_uart structure the explicit argument to
h4_recv_buf(). Every caller already has a reference to hci_uart, and
already obtains the hci_hdev reference through it, so this actually
eliminates a redundant pointer indirection for all existing callers.

Fixes: 93f06f8f0daf ("Bluetooth: remove duplicate h4_recv_buf() in header")
Reported-by: Francesco Valla <francesco@valla.it>
Closes: https://lore.kernel.org/lkml/6837167.ZASKD2KPVS@fedora.fritz.box/
Signed-off-by: Calvin Owens <calvin@wbinvd.org>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

authored by

Calvin Owens and committed by
Luiz Augusto von Dentz
b489556a 057b6ca5

+25 -19
+3 -1
drivers/bluetooth/bpa10x.c
··· 41 41 struct usb_anchor rx_anchor; 42 42 43 43 struct sk_buff *rx_skb[2]; 44 + struct hci_uart hu; 44 45 }; 45 46 46 47 static void bpa10x_tx_complete(struct urb *urb) ··· 97 96 if (urb->status == 0) { 98 97 bool idx = usb_pipebulk(urb->pipe); 99 98 100 - data->rx_skb[idx] = h4_recv_buf(hdev, data->rx_skb[idx], 99 + data->rx_skb[idx] = h4_recv_buf(&data->hu, data->rx_skb[idx], 101 100 urb->transfer_buffer, 102 101 urb->actual_length, 103 102 bpa10x_recv_pkts, ··· 389 388 hci_set_drvdata(hdev, data); 390 389 391 390 data->hdev = hdev; 391 + data->hu.hdev = hdev; 392 392 393 393 SET_HCIDEV_DEV(hdev, &intf->dev); 394 394
+3 -1
drivers/bluetooth/btmtkuart.c
··· 79 79 u16 stp_dlen; 80 80 81 81 const struct btmtkuart_data *data; 82 + struct hci_uart hu; 82 83 }; 83 84 84 85 #define btmtkuart_is_standalone(bdev) \ ··· 369 368 sz_left -= adv; 370 369 p_left += adv; 371 370 372 - bdev->rx_skb = h4_recv_buf(bdev->hdev, bdev->rx_skb, p_h4, 371 + bdev->rx_skb = h4_recv_buf(&bdev->hu, bdev->rx_skb, p_h4, 373 372 sz_h4, mtk_recv_pkts, 374 373 ARRAY_SIZE(mtk_recv_pkts)); 375 374 if (IS_ERR(bdev->rx_skb)) { ··· 859 858 } 860 859 861 860 bdev->hdev = hdev; 861 + bdev->hu.hdev = hdev; 862 862 863 863 hdev->bus = HCI_UART; 864 864 hci_set_drvdata(hdev, bdev);
+3 -1
drivers/bluetooth/btnxpuart.c
··· 212 212 struct ps_data psdata; 213 213 struct btnxpuart_data *nxp_data; 214 214 struct reset_control *pdn; 215 + struct hci_uart hu; 215 216 }; 216 217 217 218 #define NXP_V1_FW_REQ_PKT 0xa5 ··· 1757 1756 1758 1757 ps_start_timer(nxpdev); 1759 1758 1760 - nxpdev->rx_skb = h4_recv_buf(nxpdev->hdev, nxpdev->rx_skb, data, count, 1759 + nxpdev->rx_skb = h4_recv_buf(&nxpdev->hu, nxpdev->rx_skb, data, count, 1761 1760 nxp_recv_pkts, ARRAY_SIZE(nxp_recv_pkts)); 1762 1761 if (IS_ERR(nxpdev->rx_skb)) { 1763 1762 int err = PTR_ERR(nxpdev->rx_skb); ··· 1876 1875 reset_control_deassert(nxpdev->pdn); 1877 1876 1878 1877 nxpdev->hdev = hdev; 1878 + nxpdev->hu.hdev = hdev; 1879 1879 1880 1880 hdev->bus = HCI_UART; 1881 1881 hci_set_drvdata(hdev, nxpdev);
+1 -1
drivers/bluetooth/hci_ag6xx.c
··· 105 105 if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) 106 106 return -EUNATCH; 107 107 108 - ag6xx->rx_skb = h4_recv_buf(hu->hdev, ag6xx->rx_skb, data, count, 108 + ag6xx->rx_skb = h4_recv_buf(hu, ag6xx->rx_skb, data, count, 109 109 ag6xx_recv_pkts, 110 110 ARRAY_SIZE(ag6xx_recv_pkts)); 111 111 if (IS_ERR(ag6xx->rx_skb)) {
+1 -1
drivers/bluetooth/hci_aml.c
··· 650 650 struct aml_data *aml_data = hu->priv; 651 651 int err; 652 652 653 - aml_data->rx_skb = h4_recv_buf(hu->hdev, aml_data->rx_skb, data, count, 653 + aml_data->rx_skb = h4_recv_buf(hu, aml_data->rx_skb, data, count, 654 654 aml_recv_pkts, 655 655 ARRAY_SIZE(aml_recv_pkts)); 656 656 if (IS_ERR(aml_data->rx_skb)) {
+1 -1
drivers/bluetooth/hci_ath.c
··· 191 191 { 192 192 struct ath_struct *ath = hu->priv; 193 193 194 - ath->rx_skb = h4_recv_buf(hu->hdev, ath->rx_skb, data, count, 194 + ath->rx_skb = h4_recv_buf(hu, ath->rx_skb, data, count, 195 195 ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts)); 196 196 if (IS_ERR(ath->rx_skb)) { 197 197 int err = PTR_ERR(ath->rx_skb);
+1 -1
drivers/bluetooth/hci_bcm.c
··· 698 698 if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) 699 699 return -EUNATCH; 700 700 701 - bcm->rx_skb = h4_recv_buf(hu->hdev, bcm->rx_skb, data, count, 701 + bcm->rx_skb = h4_recv_buf(hu, bcm->rx_skb, data, count, 702 702 bcm_recv_pkts, ARRAY_SIZE(bcm_recv_pkts)); 703 703 if (IS_ERR(bcm->rx_skb)) { 704 704 int err = PTR_ERR(bcm->rx_skb);
+3 -3
drivers/bluetooth/hci_h4.c
··· 112 112 if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) 113 113 return -EUNATCH; 114 114 115 - h4->rx_skb = h4_recv_buf(hu->hdev, h4->rx_skb, data, count, 115 + h4->rx_skb = h4_recv_buf(hu, h4->rx_skb, data, count, 116 116 h4_recv_pkts, ARRAY_SIZE(h4_recv_pkts)); 117 117 if (IS_ERR(h4->rx_skb)) { 118 118 int err = PTR_ERR(h4->rx_skb); ··· 151 151 return hci_uart_unregister_proto(&h4p); 152 152 } 153 153 154 - struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb, 154 + struct sk_buff *h4_recv_buf(struct hci_uart *hu, struct sk_buff *skb, 155 155 const unsigned char *buffer, int count, 156 156 const struct h4_recv_pkt *pkts, int pkts_count) 157 157 { 158 - struct hci_uart *hu = hci_get_drvdata(hdev); 159 158 u8 alignment = hu->alignment ? hu->alignment : 1; 159 + struct hci_dev *hdev = hu->hdev; 160 160 161 161 /* Check for error from previous call */ 162 162 if (IS_ERR(skb))
+1 -1
drivers/bluetooth/hci_intel.c
··· 972 972 if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) 973 973 return -EUNATCH; 974 974 975 - intel->rx_skb = h4_recv_buf(hu->hdev, intel->rx_skb, data, count, 975 + intel->rx_skb = h4_recv_buf(hu, intel->rx_skb, data, count, 976 976 intel_recv_pkts, 977 977 ARRAY_SIZE(intel_recv_pkts)); 978 978 if (IS_ERR(intel->rx_skb)) {
+1 -1
drivers/bluetooth/hci_ll.c
··· 429 429 if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) 430 430 return -EUNATCH; 431 431 432 - ll->rx_skb = h4_recv_buf(hu->hdev, ll->rx_skb, data, count, 432 + ll->rx_skb = h4_recv_buf(hu, ll->rx_skb, data, count, 433 433 ll_recv_pkts, ARRAY_SIZE(ll_recv_pkts)); 434 434 if (IS_ERR(ll->rx_skb)) { 435 435 int err = PTR_ERR(ll->rx_skb);
+3 -3
drivers/bluetooth/hci_mrvl.c
··· 264 264 !test_bit(STATE_FW_LOADED, &mrvl->flags)) 265 265 return count; 266 266 267 - mrvl->rx_skb = h4_recv_buf(hu->hdev, mrvl->rx_skb, data, count, 268 - mrvl_recv_pkts, 269 - ARRAY_SIZE(mrvl_recv_pkts)); 267 + mrvl->rx_skb = h4_recv_buf(hu, mrvl->rx_skb, data, count, 268 + mrvl_recv_pkts, 269 + ARRAY_SIZE(mrvl_recv_pkts)); 270 270 if (IS_ERR(mrvl->rx_skb)) { 271 271 int err = PTR_ERR(mrvl->rx_skb); 272 272 bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err);
+2 -2
drivers/bluetooth/hci_nokia.c
··· 624 624 if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) 625 625 return -EUNATCH; 626 626 627 - btdev->rx_skb = h4_recv_buf(hu->hdev, btdev->rx_skb, data, count, 628 - nokia_recv_pkts, ARRAY_SIZE(nokia_recv_pkts)); 627 + btdev->rx_skb = h4_recv_buf(hu, btdev->rx_skb, data, count, 628 + nokia_recv_pkts, ARRAY_SIZE(nokia_recv_pkts)); 629 629 if (IS_ERR(btdev->rx_skb)) { 630 630 err = PTR_ERR(btdev->rx_skb); 631 631 dev_err(dev, "Frame reassembly failed (%d)", err);
+1 -1
drivers/bluetooth/hci_qca.c
··· 1277 1277 if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) 1278 1278 return -EUNATCH; 1279 1279 1280 - qca->rx_skb = h4_recv_buf(hu->hdev, qca->rx_skb, data, count, 1280 + qca->rx_skb = h4_recv_buf(hu, qca->rx_skb, data, count, 1281 1281 qca_recv_pkts, ARRAY_SIZE(qca_recv_pkts)); 1282 1282 if (IS_ERR(qca->rx_skb)) { 1283 1283 int err = PTR_ERR(qca->rx_skb);
+1 -1
drivers/bluetooth/hci_uart.h
··· 162 162 int h4_init(void); 163 163 int h4_deinit(void); 164 164 165 - struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb, 165 + struct sk_buff *h4_recv_buf(struct hci_uart *hu, struct sk_buff *skb, 166 166 const unsigned char *buffer, int count, 167 167 const struct h4_recv_pkt *pkts, int pkts_count); 168 168 #endif