[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CABBYNZJx+UzHLRA8o=z-fkiHAmBJ6-WtY35eJtD6C6N6PhLbDQ@mail.gmail.com>
Date: Fri, 21 Jan 2022 15:32:28 -0800
From: Luiz Augusto von Dentz <luiz.dentz@...il.com>
To: Sönke Huster <soenke.huster@...oes.de>
Cc: Marcel Holtmann <marcel@...tmann.org>,
Johan Hedberg <johan.hedberg@...il.com>,
"David S. Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>,
"linux-bluetooth@...r.kernel.org" <linux-bluetooth@...r.kernel.org>,
"open list:NETWORKING [GENERAL]" <netdev@...r.kernel.org>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>
Subject: Re: [RFC PATCH] Bluetooth: hci_event: Ignore multiple conn complete events
Hi Sönke,
On Fri, Jan 21, 2022 at 3:18 PM Sönke Huster <soenke.huster@...oes.de> wrote:
>
> Hi Luiz,
>
> On 21.01.22 22:31, Luiz Augusto von Dentz wrote:
> > Hi Sönke,
> >
> > On Fri, Jan 21, 2022 at 10:22 AM Sönke Huster <soenke.huster@...oes.de> wrote:
> >>
> >> I just noticed that just checking for handle does not work, as obviously 0x0 could also be a handle value and therefore it can't be distinguished, whether it is not set yet or it is 0x0.
> >
> > Yep, we should probably check its state, check for state != BT_OPEN
> > since that is what hci_conn_add initialize the state.
> >
>
> I thought there are more valid connection states for the first HCI_CONNECTION_COMPLETE event, as it also occurs e.g. after an HCI_Create_Connection command, see Core 5.3 p.2170:
> > This event also indicates to the Host which issued the HCI_Create_Connection, HCI_Accept_-
> > Connection_Request, or HCI_Reject_Connection_Request command, and
> > then received an HCI_Command_Status event, if the issued command failed or
> > was successful.
>
> For example in hci_conn.c hci_acl_create_connection (which triggers a HCI_Create_Connection command as far as I understand), the state of the connection is changed to BT_CONNECT or BT_CONNECT2.
> But as I am quite new in the (Linux) Bluetooth world, I might have a wrong understanding of that.
Yep, we would probably need a switch to capture which states are valid
and which are not or we initialize the handle with something outside
of the valid range of handles (0x0000 to 0x0EFF) so we can initialize
it to e.g. 0xffff (using something like define HCI_CONN_HANDLE_UNSET)
so we can really tell when it has been set or not.
> >> On 21.01.22 18:36, Soenke Huster wrote:
> >>> When a HCI_CONNECTION_COMPLETE event is received multiple times
> >>> for the same handle, the device is registered multiple times which leads
> >>> to memory corruptions. Therefore, consequent events for a single
> >>> connection are ignored.
> >>>
> >>> The conn->state can hold different values so conn->handle is
> >>> checked to detect whether a connection is already set up.
> >>>
> >>> Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=215497
> >>> Signed-off-by: Soenke Huster <soenke.huster@...oes.de>
> >>> ---
> >>> This fixes the referenced bug and several use-after-free issues I discovered.
> >>> I tagged it as RFC, as I am not 100% sure if checking the existence of the
> >>> handle is the correct approach, but to the best of my knowledge it must be
> >>> set for the first time in this function for valid connections of this event,
> >>> therefore it should be fine.
> >>>
> >>> net/bluetooth/hci_event.c | 11 +++++++++++
> >>> 1 file changed, 11 insertions(+)
> >>>
> >>> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> >>> index 681c623aa380..71ccb12c928d 100644
> >>> --- a/net/bluetooth/hci_event.c
> >>> +++ b/net/bluetooth/hci_event.c
> >>> @@ -3106,6 +3106,17 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
> >>> }
> >>> }
> >>>
> >>> + /* The HCI_Connection_Complete event is only sent once per connection.
> >>> + * Processing it more than once per connection can corrupt kernel memory.
> >>> + *
> >>> + * As the connection handle is set here for the first time, it indicates
> >>> + * whether the connection is already set up.
> >>> + */
> >>> + if (conn->handle) {
> >>> + bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection");
> >>> + goto unlock;
> >>> + }
> >>> +
> >>> if (!ev->status) {
> >>> conn->handle = __le16_to_cpu(ev->handle);
> >>>
> >
> >
> >
>
> Best
> Sönke
--
Luiz Augusto von Dentz
Powered by blists - more mailing lists