All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ v2] device: Fix race condition between device connection and disconnection
@ 2020-08-21 18:01 Sonny Sasaka
  2020-08-21 20:18 ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 2+ messages in thread
From: Sonny Sasaka @ 2020-08-21 18:01 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 | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/device.c b/src/device.c
index 7b7808405..f59b6c1d0 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,18 @@ 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] 2+ messages in thread

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

Hi Sonny,

On Fri, Aug 21, 2020 at 11:04 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 | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
>
> diff --git a/src/device.c b/src/device.c
> index 7b7808405..f59b6c1d0 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,18 @@ 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
>

Applied, thanks.

-- 
Luiz Augusto von Dentz

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

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

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

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.