1. 08 Mar, 2013 8 commits
    • Dean Jenkins's avatar
      Bluetooth: Remove RFCOMM session refcnt · 08c30aca
      Dean Jenkins authored
      Previous commits have improved the handling of the RFCOMM session
      timer and the RFCOMM session pointers such that freed RFCOMM
      session structures should no longer be erroneously accessed. The
      RFCOMM session refcnt now has no purpose and will be deleted by
      this commit.
      
      Note that the RFCOMM session is now deleted as soon as the
      RFCOMM control channel link is no longer required. This makes the
      lifetime of the RFCOMM session deterministic and absolute.
      Previously with the refcnt, there was uncertainty about when
      the session structure would be deleted because the relative
      refcnt prevented the session structure from being deleted at will.
      
      It was noted that the refcnt could malfunction under very heavy
      real-time processor loading in embedded SMP environments. This
      could cause premature RFCOMM session deletion or double session
      deletion that could result in kernel crashes. Removal of the
      refcnt prevents this issue.
      
      There are 4 connection / disconnection RFCOMM session scenarios:
      host initiated control link ---> host disconnected control link
      host initiated ctrl link ---> remote device disconnected ctrl link
      remote device initiated ctrl link ---> host disconnected ctrl link
      remote device initiated ctrl link ---> remote device disc'ed ctrl link
      
      The control channel connection procedures are independent of the
      disconnection procedures. Strangely, the RFCOMM session refcnt was
      applying special treatment so erroneously combining connection and
      disconnection events. This commit fixes this issue by removing
      some session code that used the "initiator" member of the session
      structure that was intended for use with the data channels.
      Signed-off-by: default avatarDean Jenkins <Dean_Jenkins@mentor.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      08c30aca
    • Dean Jenkins's avatar
      Bluetooth: Return RFCOMM session ptrs to avoid freed session · 8ff52f7d
      Dean Jenkins authored
      Unfortunately, the design retains local copies of the s RFCOMM
      session pointer in various code blocks and this invites the erroneous
      access to a freed RFCOMM session structure.
      
      Therefore, return the RFCOMM session pointer back up the call stack
      to avoid accessing a freed RFCOMM session structure. When the RFCOMM
      session is deleted, NULL is passed up the call stack.
      
      If active DLCs exist when the rfcomm session is terminating,
      avoid a memory leak of rfcomm_dlc structures by ensuring that
      rfcomm_session_close() is used instead of rfcomm_session_del().
      Signed-off-by: default avatarDean Jenkins <Dean_Jenkins@mentor.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      8ff52f7d
    • Dean Jenkins's avatar
      Bluetooth: Check rfcomm session and DLC exists on socket close · c06f7d53
      Dean Jenkins authored
      A race condition exists between near simultaneous asynchronous
      DLC data channel disconnection requests from the host and remote device.
      This causes the socket layer to request a socket shutdown at the same
      time the rfcomm core is processing the disconnect request from the remote
      device.
      
      The socket layer retains a copy of a struct rfcomm_dlc d pointer.
      The d pointer refers to a copy of a struct rfcomm_session.
      When the socket layer thread performs a socket shutdown, the thread
      may wait on a rfcomm lock in rfcomm_dlc_close(). This means that
      whilst the thread waits, the rfcomm_session and/or rfcomm_dlc structures
      pointed to by d maybe freed due to rfcomm core handling. Consequently,
      when the rfcomm lock becomes available and the thread runs, a
      malfunction could occur as a freed rfcomm_session structure and/or a
      freed rfcomm_dlc structure will be erroneously accessed.
      
      Therefore, after the rfcomm lock is acquired, check that the struct
      rfcomm_session is still valid by searching the rfcomm session list.
      If the session is valid then validate the d pointer by searching the
      rfcomm session list of active DLCs for the rfcomm_dlc structure
      pointed by d.
      Signed-off-by: default avatarDean Jenkins <Dean_Jenkins@mentor.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      c06f7d53
    • Dean Jenkins's avatar
      Bluetooth: Avoid rfcomm_session_timeout using freed session · fea7b02f
      Dean Jenkins authored
      Use del_timer_sync() instead of del_timer() as this ensures
      that rfcomm_session_timeout() is not running on a different
      CPU when rfcomm_session_put() is called. This avoids a race
      condition on SMP systems because potentially
      rfcomm_session_timeout() could reuse the freed RFCOMM session
      structure caused by the execution of rfcomm_session_put().
      
      Note that this modification makes the reason for the RFCOMM
      session refcnt mechanism redundant.
      Signed-off-by: default avatarDean Jenkins <Dean_Jenkins@mentor.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      fea7b02f
    • David Herrmann's avatar
      Bluetooth: change bt_sock_unregister() to return void · be9f97f0
      David Herrmann authored
      There is no reason a caller ever wants to check the return type of this
      call. _Iff_ a user successfully called bt_sock_register(), they're allowed
      to call bt_sock_unregister().
      All other calls in the kernel (device_del, device_unregister, kfree(), ..)
      that are logically equivalent return void. Lets not make callers think
      they have to check the return type of this call and instead simply return
      void.
      
      We guarantee that after bt_sock_unregister() is called, the socket type
      _is_ unregistered. If that is not what the caller wants, they're using the
      wrong function, anyway.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      be9f97f0
    • David Herrmann's avatar
      Bluetooth: discard bt_sock_unregister() errors · 5e9d7f86
      David Herrmann authored
      After we successfully registered a socket via bt_sock_register() there is
      no reason to ever check the return code of bt_sock_unregister(). If
      bt_sock_unregister() fails, it means the socket _is_ already unregistered
      so we have what we want, don't we?
      
      Also, to get bt_sock_unregister() to fail, another part of the kernel has
      to unregister _our_ socket. This is sooo _wrong_ that it will break way
      earlier than when we unregister our socket.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      5e9d7f86
    • Karl Relton's avatar
      Bluetooth: Make hidp_get_raw_report abort if the session is terminating · fd86c9be
      Karl Relton authored
      After linux 3.2 the hid_destroy_device call in hidp_session
      cleaning up invokes a hook to the power_supply code which
      in turn tries to read the battery capacity. This read will
      trigger a call to hidp_get_raw_report which is bound to fail
      because the device is being taken away - so rather than
      wait for the 5 second timeout failure this changes enables
      it to fail straight away.
      Signed-off-by: default avatarKarl Relton <karllinuxtest.relton@ntlworld.com>
      Reviewed-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      fd86c9be
    • Andre Guedes's avatar
      Bluetooth: Rename hci_acl_disconn · bed71748
      Andre Guedes authored
      As hci_acl_disconn function basically sends the HCI Disconnect Command
      and it is used to disconnect ACL, SCO and LE links, renaming it to
      hci_disconnect is more suitable.
      Signed-off-by: default avatarAndre Guedes <andre.guedes@openbossa.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      bed71748
  2. 06 Mar, 2013 32 commits