Hi Luiz, On Tue, 2 May 2023 14:25:24 -0700, Luiz Augusto von Dentz wrote: > From: Ruihan Li <lrh2000@xxxxxxxxxx> > > The hci_conn_unlink function is being called by hci_conn_del, which > means it should not call hci_conn_del with the input parameter conn > again. If it does, conn may have already been released when > hci_conn_unlink returns, leading to potential UAF and double-free > issues. > > This patch resolves the problem by modifying hci_conn_unlink to release > only conn's child links when necessary, but never release conn itself. > > Reported-by: syzbot+690b90b14f14f43f4688@xxxxxxxxxxxxxxxxxxxxxxxxx > Closes: https://lore.kernel.org/linux-bluetooth/000000000000484a8205faafe216@xxxxxxxxxx/ > Fixes: 06149746e720 ("Bluetooth: hci_conn: Add support for linking multiple hcon") > Signed-off-by: Ruihan Li <lrh2000@xxxxxxxxxx> > Reported-by: syzbot+690b90b14f14f43f4688@xxxxxxxxxxxxxxxxxxxxxxxxx > Reported-by: Luiz Augusto von Dentz <luiz.dentz@xxxxxxxxx> > Reported-by: syzbot+8bb72f86fc823817bc5d@xxxxxxxxxxxxxxxxxxxxxxxxx I don't think these tags are properly inserted in commit messages, are they? > Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> > --- > net/bluetooth/hci_conn.c | 21 ++++++++++++--------- > 1 file changed, 12 insertions(+), 9 deletions(-) > > diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c > index 640b951bf40a..70e1655a9df6 100644 > --- a/net/bluetooth/hci_conn.c > +++ b/net/bluetooth/hci_conn.c > @@ -1083,8 +1083,18 @@ static void hci_conn_unlink(struct hci_conn *conn) > if (!conn->parent) { > struct hci_link *link, *t; > > - list_for_each_entry_safe(link, t, &conn->link_list, list) > - hci_conn_unlink(link->conn); > + list_for_each_entry_safe(link, t, &conn->link_list, list) { > + struct hci_conn *child = link->conn; > + > + hci_conn_unlink(child); > + > + /* Due to race, SCO connection might be not established > + * yet at this point. Delete it now, otherwise it is > + * possible for it to be stuck and can't be deleted. > + */ > + if (child->handle == HCI_CONN_HANDLE_UNSET) > + hci_conn_del(child); > + } > > return; > } > @@ -1100,13 +1110,6 @@ static void hci_conn_unlink(struct hci_conn *conn) > > kfree(conn->link); > conn->link = NULL; > - > - /* Due to race, SCO connection might be not established > - * yet at this point. Delete it now, otherwise it is > - * possible for it to be stuck and can't be deleted. > - */ > - if (conn->handle == HCI_CONN_HANDLE_UNSET) > - hci_conn_del(conn); > } > > int hci_conn_del(struct hci_conn *conn) > -- > 2.40.0 Thanks, Ruihan Li