All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ] device: Fix race condition between device connection and disconnection
@ 2020-08-21  7:45 Sonny Sasaka
  2020-08-21 17:36 ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 3+ messages in thread
From: Sonny Sasaka @ 2020-08-21  7:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sonny Sasaka, Miao-chen Chou

When Connect() is called and waiting for return, dev_disconnected may be
called due to MGMT_EV_DEVICE_DISCONNECTED event from kernel. In that
case reply to client that the connection failed otherwise the dbus
method will timeout because bluetoothd never replies.

Tested with simulation of a lot of Connect() to bluetooth devices and
check that error is returned from bluetoothd rather than dbus timeout
when this race condition happens.

Reviewed-by: Miao-chen Chou <mcchou@chromium.org>

---
 src/device.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/src/device.c b/src/device.c
index 7b7808405..55e7b4042 100644
--- a/src/device.c
+++ b/src/device.c
@@ -3006,6 +3006,7 @@ void device_add_connection(struct btd_device *dev, uint8_t bdaddr_type)
 void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type)
 {
 	struct bearer_state *state = get_state(device, bdaddr_type);
+	DBusMessage *reply;
 
 	if (!state->connected)
 		return;
@@ -3020,6 +3021,17 @@ void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type)
 		device->disconn_timer = 0;
 	}
 
+	// This could be executed while the client is waiting for Connect() but
+	// att_connect_cb has not been invoked.
+	// In that case reply the client that the connection failed.
+	if (device->connect) {
+		DBG("connection removed while Connect() is waiting reply");
+		reply = btd_error_failed(device->connect, "Disconnected early");
+		g_dbus_send_message(dbus_conn, reply);
+		dbus_message_unref(device->connect);
+		device->connect = NULL;
+	}
+
 	while (device->disconnects) {
 		DBusMessage *msg = device->disconnects->data;
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH BlueZ] device: Fix race condition between device connection and disconnection
  2020-08-21  7:45 [PATCH BlueZ] device: Fix race condition between device connection and disconnection Sonny Sasaka
@ 2020-08-21 17:36 ` Luiz Augusto von Dentz
  2020-08-21 18:01   ` Sonny Sasaka
  0 siblings, 1 reply; 3+ messages in thread
From: Luiz Augusto von Dentz @ 2020-08-21 17:36 UTC (permalink / raw)
  To: Sonny Sasaka; +Cc: linux-bluetooth, Miao-chen Chou

Hi Sonny,

On Fri, Aug 21, 2020 at 12:47 AM Sonny Sasaka <sonnysasaka@chromium.org> wrote:
>
> When Connect() is called and waiting for return, dev_disconnected may be
> called due to MGMT_EV_DEVICE_DISCONNECTED event from kernel. In that
> case reply to client that the connection failed otherwise the dbus
> method will timeout because bluetoothd never replies.
>
> Tested with simulation of a lot of Connect() to bluetooth devices and
> check that error is returned from bluetoothd rather than dbus timeout
> when this race condition happens.
>
> Reviewed-by: Miao-chen Chou <mcchou@chromium.org>
>
> ---
>  src/device.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> diff --git a/src/device.c b/src/device.c
> index 7b7808405..55e7b4042 100644
> --- a/src/device.c
> +++ b/src/device.c
> @@ -3006,6 +3006,7 @@ void device_add_connection(struct btd_device *dev, uint8_t bdaddr_type)
>  void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type)
>  {
>         struct bearer_state *state = get_state(device, bdaddr_type);
> +       DBusMessage *reply;
>
>         if (!state->connected)
>                 return;
> @@ -3020,6 +3021,17 @@ void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type)
>                 device->disconn_timer = 0;
>         }
>
> +       // This could be executed while the client is waiting for Connect() but
> +       // att_connect_cb has not been invoked.
> +       // In that case reply the client that the connection failed.

Please use C style comment /* */

> +       if (device->connect) {
> +               DBG("connection removed while Connect() is waiting reply");
> +               reply = btd_error_failed(device->connect, "Disconnected early");
> +               g_dbus_send_message(dbus_conn, reply);
> +               dbus_message_unref(device->connect);
> +               device->connect = NULL;
> +       }
> +
>         while (device->disconnects) {
>                 DBusMessage *msg = device->disconnects->data;
>
> --
> 2.26.2
>

Otherwise it looks good.

-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH BlueZ] device: Fix race condition between device connection and disconnection
  2020-08-21 17:36 ` Luiz Augusto von Dentz
@ 2020-08-21 18:01   ` Sonny Sasaka
  0 siblings, 0 replies; 3+ messages in thread
From: Sonny Sasaka @ 2020-08-21 18:01 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth, Miao-chen Chou

Hi Luiz,

Thanks for the feedback. I have sent a v2 fixing the comment style.

On Fri, Aug 21, 2020 at 10:36 AM Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
>
> Hi Sonny,
>
> On Fri, Aug 21, 2020 at 12:47 AM Sonny Sasaka <sonnysasaka@chromium.org> wrote:
> >
> > When Connect() is called and waiting for return, dev_disconnected may be
> > called due to MGMT_EV_DEVICE_DISCONNECTED event from kernel. In that
> > case reply to client that the connection failed otherwise the dbus
> > method will timeout because bluetoothd never replies.
> >
> > Tested with simulation of a lot of Connect() to bluetooth devices and
> > check that error is returned from bluetoothd rather than dbus timeout
> > when this race condition happens.
> >
> > Reviewed-by: Miao-chen Chou <mcchou@chromium.org>
> >
> > ---
> >  src/device.c | 12 ++++++++++++
> >  1 file changed, 12 insertions(+)
> >
> > diff --git a/src/device.c b/src/device.c
> > index 7b7808405..55e7b4042 100644
> > --- a/src/device.c
> > +++ b/src/device.c
> > @@ -3006,6 +3006,7 @@ void device_add_connection(struct btd_device *dev, uint8_t bdaddr_type)
> >  void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type)
> >  {
> >         struct bearer_state *state = get_state(device, bdaddr_type);
> > +       DBusMessage *reply;
> >
> >         if (!state->connected)
> >                 return;
> > @@ -3020,6 +3021,17 @@ void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type)
> >                 device->disconn_timer = 0;
> >         }
> >
> > +       // This could be executed while the client is waiting for Connect() but
> > +       // att_connect_cb has not been invoked.
> > +       // In that case reply the client that the connection failed.
>
> Please use C style comment /* */
>
> > +       if (device->connect) {
> > +               DBG("connection removed while Connect() is waiting reply");
> > +               reply = btd_error_failed(device->connect, "Disconnected early");
> > +               g_dbus_send_message(dbus_conn, reply);
> > +               dbus_message_unref(device->connect);
> > +               device->connect = NULL;
> > +       }
> > +
> >         while (device->disconnects) {
> >                 DBusMessage *msg = device->disconnects->data;
> >
> > --
> > 2.26.2
> >
>
> Otherwise it looks good.
>
> --
> Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-08-21 18:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-21  7:45 [PATCH BlueZ] device: Fix race condition between device connection and disconnection Sonny Sasaka
2020-08-21 17:36 ` Luiz Augusto von Dentz
2020-08-21 18:01   ` Sonny Sasaka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.