This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LAUNCHXL-CC1352P: The issue of "bdb_TCProcessJoiningList" in bdb.c

Part Number: LAUNCHXL-CC1352P

Tool/software:

In function "bdb_TCProcessJoiningList", the pointer "tempJoiningDescNode" is released by "bdb_TCJoiningDeviceFree" when the "NodeJoinTimeout" of "tempJoiningDescNode" is "0", but later the pointer "tempJoiningDescNode" point to the next item from itself.  After the pointer "tempJoiningDescNode" is released, the value in "tempJoiningDescNode" is not correct.

This function can be fixed like this

void bdb_TCProcessJoiningList(void)
{
  bdb_joiningDeviceList_t* tempJoiningDescNode;

  if(bdb_joiningDeviceList)
  {
    tempJoiningDescNode = bdb_joiningDeviceList;

    while(tempJoiningDescNode)
    {
      if(tempJoiningDescNode->NodeJoinTimeout)
      {
        tempJoiningDescNode->NodeJoinTimeout--;
      }

      if(tempJoiningDescNode->NodeJoinTimeout == 0)
      {
        uint8_t isTCLKExchangeRequired = bdb_doTrustCenterRequireKeyExchange();
        //Check if the key exchange is required
        if(isTCLKExchangeRequired)
        {
            AddrMgrEntry_t entry;

            entry.user = ADDRMGR_USER_DEFAULT;
            OsalPort_memcpy(entry.extAddr,tempJoiningDescNode->bdbJoiningNodeEui64, Z_EXTADDR_LEN);

            if(AddrMgrEntryLookupExt(&entry))
            {
              ZDSecMgrAPSRemove(entry.nwkAddr,entry.extAddr,tempJoiningDescNode->parentAddr);
            }
        }

        // If we are here, a joining device has been expired due to timeout either because it is a
        // legacy device (does not perform key exchange), it is an Z3.0 device that did not perform
        // key exchange intentionally, or it is a Z3.0 device that has failed to perform key exchange.
        // Depending on our TC settings, below we decide if this joiner should be removed from the
        // security manager

        uint16_t keyNvIndex;
        uint16_t index;
        APSME_TCLinkKeyNVEntry_t TCLKDevEntry;
        uint8_t found;

        //search for the entry in the TCLK table
        keyNvIndex = APSME_SearchTCLinkKeyEntry(tempJoiningDescNode->bdbJoiningNodeEui64,&found, &TCLKDevEntry);

        uint16_t nwkAddr;
        //Look up nwkAddr before it is cleared by ZDSecMgrAddrClear
        AddrMgrNwkAddrLookup(tempJoiningDescNode->bdbJoiningNodeEui64, &nwkAddr);

        // If TC is mandating key exchange, remove devices that have not successfully performed key exchange.
        // Keep entries for ZG_PROVISIONAL_KEY so install code derived key is maintained, so joiner can reattempt join
        // If we got here and have a ZG_VERIFIED_KEY (unexpected), do not remove this entry either
        if( (isTCLKExchangeRequired == true) &&
            (TCLKDevEntry.keyAttributes != ZG_PROVISIONAL_KEY) &&
            (TCLKDevEntry.keyAttributes != ZG_VERIFIED_KEY)
          )
        {
          //Remove the entry in address manager
          ZDSecMgrAddrClear(tempJoiningDescNode->bdbJoiningNodeEui64);

          //If found, erase it.
          if(found == TRUE)
          {
            memset(&TCLKDevEntry,0,sizeof(APSME_TCLinkKeyNVEntry_t));
            TCLKDevEntry.keyAttributes = ZG_DEFAULT_KEY;

            //Increase the shift by one. Validate the maximum shift of the seed which is 15
            index = keyNvIndex;

            TCLinkKeyRAMEntry[index].rxFrmCntr = 0;
            TCLinkKeyRAMEntry[index].txFrmCntr = 0;
            TCLinkKeyRAMEntry[index].entryUsed = FALSE;

            //Update the entry
            osal_nv_write_ex( ZCD_NV_EX_TCLK_TABLE, keyNvIndex,
                              sizeof(APSME_TCLinkKeyNVEntry_t),
                              &TCLKDevEntry );
          }
        }

        if(pfnTCLinkKeyExchangeProcessCB)
        {
          bdb_TCLinkKeyExchProcess_t bdb_TCLinkKeyExchProcess;
          OsalPort_memcpy(bdb_TCLinkKeyExchProcess.extAddr,tempJoiningDescNode->bdbJoiningNodeEui64, Z_EXTADDR_LEN);
          bdb_TCLinkKeyExchProcess.nwkAddr = nwkAddr;
          bdb_TCLinkKeyExchProcess.status = BDB_TC_LK_EXCH_PROCESS_EXCH_FAIL;

          bdb_SendMsg(bdb_TaskID, BDB_TC_LINK_KEY_EXCHANGE_PROCESS, BDB_MSG_EVENT_SUCCESS,sizeof(bdb_TCLinkKeyExchProcess_t),(uint8_t*)&bdb_TCLinkKeyExchProcess);
        }
        //Free the device from the list
        //The next pointer needs to be obtained before the previous pointer is released, fixed by Luoyiming at 2025-03-06
        bdb_joiningDeviceList_t* joiningDeviceToRemove = tempJoiningDescNode;
        tempJoiningDescNode = tempJoiningDescNode->nextDev;
        bdb_TCJoiningDeviceFree(joiningDeviceToRemove);
      }
      else
      {
        //The next pointer can only be obtained when the previous pointer has not been released, fixed by Luoyiming at 2025-03-06
        tempJoiningDescNode = tempJoiningDescNode->nextDev;
      }
    }
  }

  //we are done with the list
  if(bdb_joiningDeviceList == NULL)
  {
    OsalPortTimers_stopTimer(bdb_TaskID,BDB_TC_JOIN_TIMEOUT);
  }
}