lkml.org 
[lkml]   [2015]   [Dec]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.14 25/37] Bluetooth: hidp: fix device disconnect on idle timeout
    Date
    3.14-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: David Herrmann <dh.herrmann@gmail.com>

    commit 660f0fc07d21114549c1862e67e78b1cf0c90c29 upstream.

    The HIDP specs define an idle-timeout which automatically disconnects a
    device. This has always been implemented in the HIDP layer and forced a
    synchronous shutdown of the hidp-scheduler. This works just fine, but
    lacks a forced disconnect on the underlying l2cap channels. This has been
    broken since:

    commit 5205185d461d5902325e457ca80bd421127b7308
    Author: David Herrmann <dh.herrmann@gmail.com>
    Date: Sat Apr 6 20:28:47 2013 +0200

    Bluetooth: hidp: remove old session-management

    The old session-management always forced an l2cap error on the ctrl/intr
    channels when shutting down. The new session-management skips this, as we
    don't want to enforce channel policy on the caller. In other words, if
    user-space removes an HIDP device, the underlying channels (which are
    *owned* and *referenced* by user-space) are still left active. User-space
    needs to call shutdown(2) or close(2) to release them.

    Unfortunately, this does not work with idle-timeouts. There is no way to
    signal user-space that the HIDP layer has been stopped. The API simply
    does not support any event-passing except for poll(2). Hence, we restore
    old behavior and force EUNATCH on the sockets if the HIDP layer is
    disconnected due to idle-timeouts (behavior of explicit disconnects
    remains unmodified). User-space can still call

    getsockopt(..., SO_ERROR, ...)

    ..to retrieve the EUNATCH error and clear sk_err. Hence, the channels can
    still be re-used (which nobody does so far, though). Therefore, the API
    still supports the new behavior, but with this patch it's also compatible
    to the old implicit channel shutdown.

    Reported-by: Mark Haun <haunma@keteu.org>
    Reported-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
    Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
    Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    net/bluetooth/hidp/core.c | 14 ++++++++++++++
    1 file changed, 14 insertions(+)

    --- a/net/bluetooth/hidp/core.c
    +++ b/net/bluetooth/hidp/core.c
    @@ -415,6 +415,20 @@ static void hidp_idle_timeout(unsigned l
    {
    struct hidp_session *session = (struct hidp_session *) arg;

    + /* The HIDP user-space API only contains calls to add and remove
    + * devices. There is no way to forward events of any kind. Therefore,
    + * we have to forcefully disconnect a device on idle-timeouts. This is
    + * unfortunate and weird API design, but it is spec-compliant and
    + * required for backwards-compatibility. Hence, on idle-timeout, we
    + * signal driver-detach events, so poll() will be woken up with an
    + * error-condition on both sockets.
    + */
    +
    + session->intr_sock->sk->sk_err = EUNATCH;
    + session->ctrl_sock->sk->sk_err = EUNATCH;
    + wake_up_interruptible(sk_sleep(session->intr_sock->sk));
    + wake_up_interruptible(sk_sleep(session->ctrl_sock->sk));
    +
    hidp_session_terminate(session);
    }




    \
     
     \ /
      Last update: 2015-12-07 15:41    [W:8.040 / U:3.116 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site