Skip to content
  • Johan Hedberg's avatar
    Bluetooth: Add strict checks for allowed SMP PDUs · b28b4943
    Johan Hedberg authored
    
    
    SMP defines quite clearly when certain PDUs are to be expected/allowed
    and when not, but doesn't have any explicit request/response definition.
    So far the code has relied on each PDU handler to behave correctly if
    receiving PDUs at an unexpected moment, however this requires many
    different checks and is prone to errors.
    
    This patch introduces a generic way to keep track of allowed PDUs and
    thereby reduces the responsibility & load on individual command
    handlers. The tracking is implemented using a simple bit-mask where each
    opcode maps to its own bit. If the bit is set the corresponding PDU is
    allow and if the bit is not set the PDU is not allowed.
    
    As a simple example, when we send the Pairing Request we'd set the bit
    for Pairing Response, and when we receive the Pairing Response we'd
    clear the bit for Pairing Response.
    
    Since the disallowed PDU rejection is now done in a single central place
    we need to be a bit careful of which action makes most sense to all
    cases. Previously some, such as Security Request, have been simply
    ignored whereas others have caused an explicit disconnect.
    
    The only PDU rejection action that keeps good interoperability and can
    be used for all the applicable use cases is to drop the data. This may
    raise some concerns of us now being more lenient for misbehaving (and
    potentially malicious) devices, but the policy of simply dropping data
    has been a successful one for many years e.g. in L2CAP (where this is
    the *only* policy for such cases - we never request disconnection in
    l2cap_core.c because of bad data). Furthermore, we cannot prevent
    connected devices from creating the SMP context (through a Security or
    Pairing Request), and once the context exists looking up the
    corresponding bit for the received opcode and deciding to reject it is
    essentially an equally lightweight operation as the kind of rejection
    that l2cap_core.c already successfully does.
    
    Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
    Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
    b28b4943