Skip to content

Commit ec6659a

Browse files
wzyy2rkhuangtao
authored andcommitted
UPSTREAM: Bluetooth: hci_ldisc: Fix null pointer derefence in case of early data
HCI_UART_PROTO_SET flag is set before hci_uart_set_proto call. If we receive data from tty layer during this procedure, proto pointer may not be assigned yet, leading to null pointer dereference in rx method hci_uart_tty_receive. This patch fixes this issue by introducing HCI_UART_PROTO_READY flag in order to avoid any proto operation before proto opening and assignment. Signed-off-by: Loic Poulain <loic.poulain@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Change-Id: Ibe366f3222cbe7a093cd08aaecbc0de1004088c8 Signed-off-by: Jacob Chen <jacob2.chen@rock-chips.com> (cherry picked from commit 84cb3df)
1 parent 91737eb commit ec6659a

2 files changed

Lines changed: 8 additions & 4 deletions

File tree

drivers/bluetooth/hci_ldisc.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ static int hci_uart_flush(struct hci_dev *hdev)
227227
tty_ldisc_flush(tty);
228228
tty_driver_flush_buffer(tty);
229229

230-
if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
230+
if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
231231
hu->proto->flush(hu);
232232

233233
return 0;
@@ -497,14 +497,15 @@ static void hci_uart_tty_close(struct tty_struct *tty)
497497

498498
cancel_work_sync(&hu->write_work);
499499

500-
if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
500+
if (test_and_clear_bit(HCI_UART_PROTO_READY, &hu->flags)) {
501501
if (hdev) {
502502
if (test_bit(HCI_UART_REGISTERED, &hu->flags))
503503
hci_unregister_dev(hdev);
504504
hci_free_dev(hdev);
505505
}
506506
hu->proto->close(hu);
507507
}
508+
clear_bit(HCI_UART_PROTO_SET, &hu->flags);
508509

509510
kfree(hu);
510511
}
@@ -531,7 +532,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
531532
if (tty != hu->tty)
532533
return;
533534

534-
if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
535+
if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
535536
hci_uart_tx_wakeup(hu);
536537
}
537538

@@ -555,7 +556,7 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data,
555556
if (!hu || tty != hu->tty)
556557
return;
557558

558-
if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
559+
if (!test_bit(HCI_UART_PROTO_READY, &hu->flags))
559560
return;
560561

561562
/* It does not need a lock here as it is already protected by a mutex in
@@ -643,9 +644,11 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id)
643644
return err;
644645

645646
hu->proto = p;
647+
set_bit(HCI_UART_PROTO_READY, &hu->flags);
646648

647649
err = hci_uart_register_dev(hu);
648650
if (err) {
651+
clear_bit(HCI_UART_PROTO_READY, &hu->flags);
649652
p->close(hu);
650653
return err;
651654
}

drivers/bluetooth/hci_uart.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ struct hci_uart {
9494
/* HCI_UART proto flag bits */
9595
#define HCI_UART_PROTO_SET 0
9696
#define HCI_UART_REGISTERED 1
97+
#define HCI_UART_PROTO_READY 2
9798

9899
/* TX states */
99100
#define HCI_UART_SENDING 1

0 commit comments

Comments
 (0)