Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db065032 authored by Martin Brabham's avatar Martin Brabham
Browse files

Security: Wait for name request in link key notification

For classic SSP numeric comparison we must wait at the
UserConfirmationRequest in order to get the name before
we display it to the user.  However, in the Out of Band
data flow we never get a UserConfirmationRequest.

Thus, we must wait in the link key notification if we
have not yet received a name response.

Remove setting to std::nullopt as the operator= in
std::optional causes the underlying pointer to be reset
and thus freed, but still accessed by the pointer we passed.

Bug: 175033589
Test: cert/run SecurityTest:test_successful_dut_initiated_ssp_oob --repeat=20
Tag: #gd-refactor
Change-Id: Ic3f424e22a0c596b21969d4882d0a9b06f7433ab
parent d9904535
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -132,9 +132,13 @@ void ClassicPairingHandler::OnNameRequestComplete(hci::Address address, bool suc
    device_name_ = tmp_name;
  }
  has_gotten_name_response_ = true;
  // For SSP/Numeric comparison flow
  if (user_confirmation_request_) {
    this->OnReceive(*user_confirmation_request_);
    user_confirmation_request_ = std::nullopt;
  }
  // For OOB Flow; we go to link key notification and must wait for name
  if (link_key_notification_) {
    this->OnReceive(*link_key_notification_);
  }
}

@@ -192,6 +196,10 @@ void ClassicPairingHandler::OnReceive(hci::LinkKeyNotificationView packet) {
  LOG_INFO("Received: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
  ASSERT_LOG(GetRecord()->GetPseudoAddress()->GetAddress() == packet.GetBdAddr(), "Address mismatch");
  GetRecord()->SetLinkKey(packet.GetLinkKey(), packet.GetKeyType());
  if (!has_gotten_name_response_) {
    link_key_notification_ = std::make_optional<hci::LinkKeyNotificationView>(packet);
    return;
  }
  Cancel();
}

@@ -273,7 +281,6 @@ void ClassicPairingHandler::OnReceive(hci::IoCapabilityResponseView packet) {
  has_gotten_io_cap_response_ = true;
  if (user_confirmation_request_) {
    this->OnReceive(*user_confirmation_request_);
    user_confirmation_request_ = std::nullopt;
  }
}

@@ -393,6 +400,7 @@ void ClassicPairingHandler::OnReceive(hci::KeypressNotificationView packet) {

void ClassicPairingHandler::OnReceive(hci::UserConfirmationRequestView packet) {
  // Ensure we have io cap response otherwise checks will be wrong if it comes late
  // Ensure we have the name response otherwise we cannot show a name for the device to the user
  if (!has_gotten_io_cap_response_ || !has_gotten_name_response_) {
    user_confirmation_request_ = std::make_optional<hci::UserConfirmationRequestView>(packet);
    return;
+1 −0
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ class ClassicPairingHandler : public PairingHandler {
  bool has_gotten_io_cap_response_ = false;
  bool has_gotten_name_response_ = false;
  std::optional<hci::UserConfirmationRequestView> user_confirmation_request_ = std::nullopt;
  std::optional<hci::LinkKeyNotificationView> link_key_notification_ = std::nullopt;

  hci::ErrorCode last_status_ = hci::ErrorCode::UNKNOWN_HCI_COMMAND;
  bool locally_initiated_ = false;