When RFCOMM_RELEASE_ONHUP is set, the rfcomm tty driver 'takes over'
the initial rfcomm_dev reference created by the RFCOMMCREATEDEV ioctl.
The assumption is that the rfcomm tty driver will release the
rfcomm_dev reference when the tty is freed (in rfcomm_tty_cleanup()).
However, if the tty is never opened, the 'take over' never occurs,
so when RFCOMMRELEASEDEV ioctl is called, the reference is not
released.
Track the state of the reference 'take over' so that the release
is guaranteed by either the RFCOMMRELEASEDEV ioctl or the rfcomm tty
driver.
Note that the synchronous hangup in rfcomm_release_dev() ensures
that rfcomm_tty_install() cannot race with the RFCOMMRELEASEDEV ioctl.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Tested-By: Alexander Holler <holler@ahsoftware.de>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
No logic prevents an rfcomm_dev from being released multiple
times. For example, if the rfcomm_dev ref count is large due
to pending tx, then multiple RFCOMMRELEASEDEV ioctls may
mistakenly release the rfcomm_dev too many times. Note that
concurrent ioctls are not required to create this condition.
Introduce RFCOMM_DEV_RELEASED status bit which guarantees the
rfcomm_dev can only be released once.
NB: Since the flags are exported to userspace, introduce the status
field to track state for which userspace should not be aware.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Tested-By: Alexander Holler <holler@ahsoftware.de>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
When enumerating RFCOMM devices in the rfcomm_dev_list, holding
the rfcomm_dev_lock only guarantees the existence of the enumerated
rfcomm_dev in memory, and not safe access to its state. Testing
the device state (such as RFCOMM_TTY_RELEASED) does not guarantee
the device will remain in that state for the subsequent access
to the rfcomm_dev's fields, nor guarantee that teardown has not
commenced.
Obtain an rfcomm_dev reference for the duration of rfcomm_dev
access.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Tested-By: Alexander Holler <holler@ahsoftware.de>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
rfcomm_dev_get() can return a rfcomm_dev reference for a
device for which destruction may be commencing. This can happen
on tty destruction, which calls rfcomm_tty_cleanup(), the last
port reference may have been released but RFCOMM_TTY_RELEASED
was not set. The following race is also possible:
CPU 0 | CPU 1
| rfcomm_release_dev
rfcomm_dev_get | .
spin_lock | .
dev = __rfcomm_dev_get | .
if dev | .
if test_bit(TTY_RELEASED) | .
| !test_and_set_bit(TTY_RELEASED)
| tty_port_put <<<< last reference
else |
tty_port_get |
The reference acquire is bogus because destruction will commence
with the release of the last reference.
Ignore the external state change of TTY_RELEASED and instead rely
on the reference acquire itself to determine if the reference is
valid.
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Tested-By: Alexander Holler <holler@ahsoftware.de>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
The tty core supports two models for handling tty_port lifetimes;
the tty_port can use the kref supplied by tty_port (which will
automatically destruct the tty_port when the ref count drops to
zero) or it can destruct the tty_port manually.
For tty drivers that choose to use the port kref to manage the
tty_port lifetime, it is not possible to safely acquire a port
reference conditionally. If the last reference is released after
evaluating the condition but before acquiring the reference, a
bogus reference will be held while the tty_port destruction
commences.
Rather, only acquire a port reference if the ref count is non-zero
and allow the caller to distinguish if a reference has successfully
been acquired.
Cc: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Tested-By: Alexander Holler <holler@ahsoftware.de>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This reverts commit e228b63390.
This is the third of a 3-patch revert, together with
Revert "Bluetooth: Remove rfcomm_carrier_raised()" and
Revert "Bluetooth: Always wait for a connection on RFCOMM open()".
Commit 4a2fb3ecc7,
"Bluetooth: Always wait for a connection on RFCOMM open()" open-codes
blocking on tty open(), rather than using the default behavior
implemented by the tty port.
The reasons for reverting that patch are detailed in that changelog;
this patch restores required functionality for that revert.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Tested-By: Alexander Holler <holler@ahsoftware.de>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This reverts commit 4a2fb3ecc7.
This is the second of a 3-patch revert, together with
Revert "Bluetooth: Remove rfcomm_carrier_raised()" and
Revert "Bluetooth: Move rfcomm_get_device() before rfcomm_dev_activate()".
Before commit cad348a17e,
Bluetooth: Implement .activate, .shutdown and .carrier_raised methods,
tty_port_block_til_ready() was open-coded in rfcomm_tty_install() as
part of the RFCOMM tty open().
Unfortunately, it did not implement non-blocking open nor CLOCAL open,
but rather always blocked for carrier. This is not the expected or
typical behavior for ttys, and prevents several common terminal
programming idioms from working (eg., opening in non-blocking
mode to initialize desired termios settings then re-opening for
connection).
Commit cad348a17e,
Bluetooth: Implement .activate, .shutdown and .carrier_raised methods,
added the necessary tty_port methods to use the default tty_port_open().
However, this triggered two important user-space regressions.
The first regression involves the complicated mechanism for reparenting
the rfcomm tty device to the ACL link device which represents an
open link to a specific bluetooth host. This regression causes ModemManager
to conclude the rfcomm tty device does not front a modem so it makes
no attempt to initialize an attached modem. This regression is
caused by the lack of a device_move() if the dlc is already open (and
not specifically related to the open-coded block_til_ready()).
A more appropriate solution is submitted in
"Bluetooth: Fix unsafe RFCOMM device parenting" and
"Bluetooth: Fix RFCOMM parent device for reused dlc"
The second regression involves "rfcomm bind" and wvdial (a ppp dialer).
rfcomm bind creates a device node for a /dev/rfcomm<n>. wvdial opens
that device in non-blocking mode (because it expects the connection
to have already been established). In addition, subsequent writes
to the rfcomm tty device fail (because the link is not yet connected;
rfcomm connection begins with the actual tty open()).
However, restoring the original behavior (in the patch which
this reverts) was undesirable.
Firstly, the original reporter notes that a trivial userspace
"workaround" already exists: rfcomm connect, which creates the
device node and establishes the expected connection.
Secondly, the failed writes occur because the rfcomm tty driver
does not buffer writes to an unconnected device; this contrasts with
the dozen of other tty drivers (in fact, all of them) that do just
that. The submitted patch "Bluetooth: Don't fail RFCOMM tty writes"
corrects this.
Thirdly, it was a long-standing bug to block on non-blocking open,
which is re-fixed by revert.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Tested-By: Alexander Holler <holler@ahsoftware.de>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This reverts commit f86772af6a.
This is the first of a 3-patch revert, together with
Revert "Bluetooth: Always wait for a connection on RFCOMM open()" and
Revert "Bluetooth: Move rfcomm_get_device() before rfcomm_dev_activate()".
Commit 4a2fb3ecc7,
"Bluetooth: Always wait for a connection on RFCOMM open()" open-codes
blocking on tty open(), rather than using the default behavior
implemented by the tty port.
The reasons for reverting that patch are detailed in that changelog;
this patch restores required functionality for that revert.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Tested-By: Alexander Holler <holler@ahsoftware.de>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Now that the LE L2CAP Connection Oriented Channel support has undergone a
decent amount of testing we can make it officially supported. This patch
removes the enable_lecoc module parameter which was previously needed to
enable support for LE L2CAP CoC.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This patch changes hci_connect_le() so it uses the connection
parameters specified for the certain device. If no parameters
were configured, we use the default values.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This patch adds to hdev the connection parameters list (hdev->le_
conn_params). The elements from this list (struct hci_conn_params)
contains the connection parameters (for now, minimum and maximum
connection interval) that should be used during the connection
establishment.
Moreover, this patch adds helper functions to manipulate hdev->le_
conn_params list. Some of these functions are also declared in
hci_core.h since they will be used outside hci_core.c in upcoming
patches.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
The LTK key types available right now are unauthenticated and
authenticated ones. Provide two simple constants for it.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
When the ACL link is using P-256 authenticated combination key, mark
the link mode as HCI_LM_FIPS.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This check is only used for RFCOMM connections and most likely no
RFCOMM based profile will require security level 4 secure connection
security policy. In case it ever does make sure that seucrity level 4
is treated as sufficient security level.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
With support for Secure Connections it is possible to switch the
controller into a mode that is called Secure Connections Only. In
this mode only security level 4 connections are allowed (with the
exception of security level 0 approved services).
This patch just introduces the management command and setting of the
right internal flags to enable this mode. It does not yet enforce it.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
The struct smp_ltk does not need to be packed and so remove __packed.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
The field is not a boolean, it is actually a field for a key type. So
name it properly.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
The LTK authenticated parameter is the key type of the LTK and similar
to link keys there is no need to check the currently supported values.
For possible future improvements, the kernel will only use key types
it knows about and just ignore all the other ones.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
When encryption for LE links has been enabled, it will always be use
AES-CCM encryption. In case of BR/EDR Secure Connections, the link
will also use AES-CCM encryption. In both cases track the AES-CCM
status in the connection flags.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
The function already has an unlock label which means the one extra level
on indentation is not useful and just makes the code more complex. So
remove it.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Since the use of debug keys can now be identified from the current
settings information, this debugfs entry is no longer necessary.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Originally allowing the use of debug keys was done via the Load Link
Keys management command. However this is BR/EDR specific and to be
flexible and allow extending this to LE as well, make this an independent
command.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
When the controller has been enabled to allow usage of debug keys, then
clearly identify that in the current settings information.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This patch moves connection attempt failure code to its own function
so it can be reused in the next patch.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This patch groups the list_head fields from struct hci_dev together
and removes empty lines between them.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This patch creates two new fields in struct hci_conn to save the
minimum and maximum connection interval values used to establish
the connection this object represents.
This change is required in order to know what parameters the
connection is currently using.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
If LTK distribution happens in both directions we will have two LTKs for
the same remote device: one which is used when we're connecting as
master and another when we're connecting as slave. When looking up LTKs
from the locally stored list we shouldn't blindly return the first match
but also consider which type of key is in question. If we do not do this
we may end up selecting an incorrect encryption key for a connection.
This patch fixes the issue by always specifying to the LTK lookup
functions whether we're looking for a master or a slave key.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
All callers of hci_add_ltk pass a valid value to it. There are no places
where e.g. user space, the controller or the remote peer would be able
to cause invalid values to be passed. Therefore, just remove the
potentially confusing check from the beginning of the function.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Instead of magic bitwise operations simply compare with the two possible
type values that we are interested in.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
The code was previously iterating the wrong list (and what's worse
casting entries to a type which they were not) and also missing a proper
line terminator when printing each entry. The code now also prints the
LTK type in hex for easier comparison with the kernel-defined values.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Starting with the 4.1 Core Specification these flags are no longer used
and should always be cleared. From volume 3, part C, section 13.1.1:
"The 'Simultaneous LE and BR/EDR to Same Device Capable (Controller)'
and ‘Simultaneous LE and BR/EDR to Same Device Capable (Host)’ bits in
the Flags AD type shall be set to ‘0’."
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
So far we've only been requesting the LTK to be distributed to the
master (initiator) of pairing, which is usually enough since it's the
master that will establish future connections and initiate encryption.
However, in the case that both devices support switching to the opposing
role (which seems to be increasingly common) pairing will have to
performed again since the "new" master will not have all information.
As there is no real harm in it, this patch updates the code to always
try distributing the LTK also to the slave device, thereby enabling role
switches for future connections.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Vinicius Gomes <vcgomes@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This patch increments the management interface revision due to the
various fixes, improvements and other changes that have been made.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Now that ATT sockets have been converted to use the new L2CAP_CHAN_FIXED
type there is no need to have an extra check for chan->psm in the
l2cap_chan_close function.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
The l2cap_chan->psm value is always set to a valid value for a
connection oriented channel. The l2cap_chan->sport is used for tracking
local PSM allocations but will not always have a proper value, such as
with connected sockets derived from a listening socket. This patch fixes
the sock_getname callback to always use chan->psm when returning address
information.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
When we're not connected the peer address information is undefined. This
patch fixes the remote address getting to return a proper error in case
the sate is anything else than BT_CONNECTED.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
When we're not connected the peer address information is undefined. This
patch fixes the remote address getting to return a proper error in case
the state is anything else than BT_CONNECTED.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
The sport variable is used to track the allocation of the local PSM
database to ensure no two sockets take the same local PSM. It is
acquired upon bind() but needs to be freed up if the socket ends up
becoming a client one. This patch adds the clearing of the value when
l2cap_chan_connect is called.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
The L2CAP specification requires us to disconnect an L2CAP channel if
the remote side gives us credits beyond 65535. This patch makes sure we
disconnect the channel in such a situation.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
The L2CAP specification requires us to disconnect a channel if the
remote device sends us data when it doesn't have any credits to do so.
This patch makes sure that we send the appropriate L2CAP Disconnect
request in this situation.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
There's a le_default_mps variable that can be modified through debugfs
but it was never actually used for determining our MPS value. This patch
fixes the MPS initialization to use the variable instead of a fixed
value.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Fixed channels have the same source and destination CID. Ensure that the
values get properly initialized when receiving incoming connections and
deriving values from the parent socket.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
The BT_SECURITY option should also be allowed for fixed channels, so
punch the appropriate hole for it when checking for the channel type.
The main user of fixed CID user space sockets is right now ATT (which is
broken without this patch).
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
ATT channels are not connection oriented so having them use
L2CAP_CHAN_CONN_ORIENTED is quite confusing. Instead, use the new
L2CAP_CHAN_FIXED type and ensure that the MTU and CID values get
properly set.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
There's no reason why A2MP should need or deserve its on channel type.
Instead we should be able to group all fixed CID users under a single
channel type and reuse as much code as possible for them. Where CID
specific exceptions are needed the chan-scid value can be used.
This patch renames the current A2MP channel type to a generic one and
thereby paves the way to allow converting ATT and SMP (and any future
fixed channel protocols) to use the new channel type.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
The only user of l2cap_seq_list_remove() was l2cap_seq_list_pop() which
only removes the head, meaning only the "else if (seq_list->head ==
seq)" branch was ever being used. This patch moves the code from this
branch straight into l2cap_seq_list_pop() and removes the (now useless)
l2cap_seq_list_remove().
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This patch adds a queue for incoming L2CAP data that's received before
l2cap_connect_cfm is called and processes the data once
l2cap_connect_cfm is called. This way we ensure that we have e.g. all
remote features before processing L2CAP signaling data (which is very
important for making the correct security decisions).
The processing of the pending rx data needs to be done through
queue_work since unlike l2cap_recv_acldata, l2cap_connect_cfm is called
with the hci_dev lock held which could cause potential deadlocks.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This patch moves the l2cap_conn_add, is_valid_psm and l2cap_chan_connect
functions further down in l2cap_core.c. The patch doesn't contain
anything else except the relocation of these functions. By moving the
functions further down the patch enables a subsequent patch that adds a
pending RX queue to be implemented without a forward declaration of a
function.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>