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

Commit 4fd319ca authored by Vance Yu's avatar Vance Yu
Browse files

Fix a race condition when creating rfcomm servers

It is a race condition issue between 2 rfcomm server connection with the
same channel number. I changed the SCN allocated policy. BT stack
always allocate new SCN even the SCN has been released.

Test: manual test
Bug: 243974739
Change-Id: I0e535ff846f6745a9d6225ddb231f9ec3f8f7a19
parent 5a00b850
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -363,6 +363,7 @@ typedef struct tBTM_CB {
        kBtmLogHistoryBufferSize);
    CHECK(history_ != nullptr);
    history_->Push(std::string("Initialized btm history"));
    btm_available_index = 1;
  }

  void Free() {
@@ -396,6 +397,7 @@ typedef struct tBTM_CB {
  friend bool BTM_TryAllocateSCN(uint8_t scn);
  friend bool BTM_FreeSCN(uint8_t scn);
  uint8_t btm_scn[BTM_MAX_SCN_];
  uint8_t btm_available_index;
} tBTM_CB;

/* security action for L2CAP COC channels */
+16 −2
Original line number Diff line number Diff line
@@ -32,17 +32,31 @@ extern tBTM_CB btm_cb;
 *
 ******************************************************************************/
uint8_t BTM_AllocateSCN(void) {
  uint8_t x;
  BTM_TRACE_DEBUG("BTM_AllocateSCN");

  // stack reserves scn 1 for HFP, HSP we still do the correct way
  for (x = 1; x < PORT_MAX_RFC_PORTS; x++) {
  for (uint8_t x = btm_cb.btm_available_index; x < PORT_MAX_RFC_PORTS; x++) {
    if (!btm_cb.btm_scn[x]) {
      btm_cb.btm_scn[x] = true;
      btm_cb.btm_available_index = (x + 1);
      return (x + 1);
    }
  }

  // In order to avoid OOB, btm_available_index must be less than or equal to
  // PORT_MAX_RFC_PORTS
  btm_cb.btm_available_index =
      std::min(btm_cb.btm_available_index, (uint8_t)PORT_MAX_RFC_PORTS);

  // If there's no empty SCN from _last_index to BTM_MAX_SCN.
  for (uint8_t y = 1; y < btm_cb.btm_available_index; y++) {
    if (!btm_cb.btm_scn[y]) {
      btm_cb.btm_scn[y] = true;
      btm_cb.btm_available_index = (y + 1);
      return (y + 1);
    }
  }

  return (0); /* No free ports */
}