Update LoRaMac-node to Version 4.4.4,fix Security breach found by Tencent Blade Team please refer to security advisory - CVE-2020-11068

fix Security breach found by Tencent Blade Team please refer to security advisory - CVE-2020-11068
This commit is contained in:
supowang
2020-05-29 11:59:05 +08:00
parent 5d9895cecc
commit f9bd2588a2
137 changed files with 10401 additions and 4328 deletions

View File

@@ -17,27 +17,23 @@ License: Revised BSD License, see LICENSE.TXT file include in the project
Maintainer: Miguel Luis ( Semtech ), Daniel Jaeckle ( STACKFORCE ), Johannes Bruder ( STACKFORCE )
*/
#include <stddef.h>
#include "utilities.h"
#include "LoRaMacCommands.h"
#include "LoRaMacConfirmQueue.h"
/*
/*!
* Number of MAC Command slots
*/
#define NUM_OF_MAC_COMMANDS 15
/*
/*!
* Size of the CID field of MAC commands
*/
#define CID_FIELD_SIZE 1
#define CID_FIELD_SIZE 1
/*
* List of all stick MAC command answers which will be deleted after a receiving downlink
*/
const uint8_t CIDsStickyAnsCmds[] = { MOTE_MAC_DL_CHANNEL_ANS, MOTE_MAC_RX_PARAM_SETUP_ANS, MOTE_MAC_RX_TIMING_SETUP_ANS };
/*
/*!
* Mac Commands list structure
*/
typedef struct sMacCommandsList
@@ -52,7 +48,7 @@ typedef struct sMacCommandsList
MacCommand_t* Last;
} MacCommandsList_t;
/*
/*!
* LoRaMac Commands Context structure
*/
typedef struct sLoRaMacCommandsCtx
@@ -71,27 +67,27 @@ typedef struct sLoRaMacCommandsCtx
size_t SerializedCmdsSize;
} LoRaMacCommandsCtx_t;
/*
/*!
* Callback function to notify the upper layer about context change
*/
static EventNvmCtxChanged CommandsNvmCtxChanged;
static LoRaMacCommandsNvmEvent CommandsNvmCtxChanged;
/*
/*!
* Non-volatile module context.
*/
static LoRaMacCommandsCtx_t NvmCtx;
/* Memory management functions */
/*
/*!
* \brief Determines if a MAC command slot is free
*
* \param[IN] slot - Slot to check
* \retval - Status of the operation
*/
bool isSlotFree( const MacCommand_t* slot )
static bool IsSlotFree( const MacCommand_t* slot )
{
uint8_t* mem = (uint8_t*) slot;
uint8_t* mem = ( uint8_t* )slot;
for( uint16_t size = 0; size < sizeof( MacCommand_t ); size++ )
{
@@ -103,114 +99,112 @@ bool isSlotFree( const MacCommand_t* slot )
return true;
}
/*
/*!
* \brief Allocates a new MAC command memory slot
*
* \retval - Pointer to slot
*/
MacCommand_t* mallocNewMacCommandSlot( )
static MacCommand_t* MallocNewMacCommandSlot( void )
{
uint8_t itr = 0;
while( isSlotFree( ( const MacCommand_t* ) &NvmCtx.MacCommandSlots[itr]) == false )
while( IsSlotFree( ( const MacCommand_t* )&NvmCtx.MacCommandSlots[itr] ) == false )
{
itr++;
if( itr == NUM_OF_MAC_COMMANDS )
{
return 0;
return NULL;
}
}
return &NvmCtx.MacCommandSlots[itr];
}
/*
/*!
* \brief Free memory slot
*
* \param[IN] slot - Slot to free
*
* \retval - Status of the operation
*/
bool freeMacCommandSlot( MacCommand_t* slot )
static bool FreeMacCommandSlot( MacCommand_t* slot )
{
if( slot == 0 )
if( slot == NULL )
{
return false;
}
memset1( (uint8_t*) slot, 0x00, sizeof( MacCommand_t ));
memset1( ( uint8_t* )slot, 0x00, sizeof( MacCommand_t ) );
return true;
}
/* Linked list functions */
/*
/*!
* \brief Initialize list
*
* \param[IN] list - List that shall be initialized
* \retval - Status of the operation
*/
static bool linkedListInit( MacCommandsList_t* list )
static bool LinkedListInit( MacCommandsList_t* list )
{
if( list == 0 )
if( list == NULL )
{
return false;
}
list->First = 0;
list->Last = 0;
list->First = NULL;
list->Last = NULL;
return true;
}
/*
/*!
* \brief Add an element to the list
*
* \param[IN] list - List where the element shall be added.
* \param[IN] element - Element to add
* \retval - Status of the operation
*/
static bool linkedListAdd( MacCommandsList_t* list, MacCommand_t* element )
static bool LinkedListAdd( MacCommandsList_t* list, MacCommand_t* element )
{
if( ( list == 0 ) && ( element == 0 ) )
if( ( list == NULL ) || ( element == NULL ) )
{
return false;
}
/* Check if this is the first entry to enter the list. */
if( list->First == 0 )
// Check if this is the first entry to enter the list.
if( list->First == NULL )
{
list->First = element;
}
/* Check if the last entry exists and update its next point. */
// Check if the last entry exists and update its next point.
if( list->Last )
{
list->Last->Next = element;
}
/* Update the next point of this entry. */
element->Next = 0;
// Update the next point of this entry.
element->Next = NULL;
/* Update the last entry of the list. */
// Update the last entry of the list.
list->Last = element;
return true;
}
/*
/*!
* \brief Return the previous element in the list.
*
* \param[IN] list - List
* \param[IN] element - Element where the previous element shall be searched
* \retval - Status of the operation
*/
static MacCommand_t* linkedListGetPrevious( MacCommandsList_t* list, MacCommand_t* element )
static MacCommand_t* LinkedListGetPrevious( MacCommandsList_t* list, MacCommand_t* element )
{
if( ( list == 0 ) && ( element == 0 ) )
if( ( list == NULL ) || ( element == NULL ) )
{
return NULL;
}
@@ -220,14 +214,11 @@ static MacCommand_t* linkedListGetPrevious( MacCommandsList_t* list, MacCommand_
// Start at the head of the list
curElement = list->First;
/*
* When current element is the first of the list, there's no previous element so we can return NULL immediately.
*/
if( element != curElement)
// When current element is the first of the list, there's no previous element so we can return NULL immediately.
if( element != curElement )
{
// Loop through all elements until the end is reached or the next of current is the current element.
while(curElement && (curElement->Next != element))
while( ( curElement != NULL ) && ( curElement->Next != element ) )
{
curElement = curElement->Next;
}
@@ -240,21 +231,21 @@ static MacCommand_t* linkedListGetPrevious( MacCommandsList_t* list, MacCommand_
return curElement;
}
/*
/*!
* \brief Remove an element from the list
*
* \param[IN] list - List where the element shall be removed from.
* \param[IN] element - Element to remove
* \retval - Status of the operation
*/
static bool linkedListRemove( MacCommandsList_t* list, MacCommand_t* element )
static bool LinkedListRemove( MacCommandsList_t* list, MacCommand_t* element )
{
if( ( list == 0 ) && ( element == 0 ) )
if( ( list == NULL ) || ( element == NULL ) )
{
return false;
}
MacCommand_t* PrevElement = linkedListGetPrevious( list, element );
MacCommand_t* PrevElement = LinkedListGetPrevious( list, element );
if( list->First == element )
{
@@ -266,12 +257,12 @@ static bool linkedListRemove( MacCommandsList_t* list, MacCommand_t* element )
list->Last = PrevElement;
}
if( PrevElement )
if( PrevElement != NULL )
{
PrevElement->Next = element->Next;
}
element->Next = 0;
element->Next = NULL;
return true;
}
@@ -290,6 +281,7 @@ static bool IsSticky( uint8_t cid )
case MOTE_MAC_DL_CHANNEL_ANS:
case MOTE_MAC_RX_PARAM_SETUP_ANS:
case MOTE_MAC_RX_TIMING_SETUP_ANS:
case MOTE_MAC_TX_PARAM_SETUP_ANS:
return true;
default:
return false;
@@ -307,13 +299,12 @@ static void NvmCtxCallback( void )
}
}
LoRaMacCommandStatus_t LoRaMacCommandsInit( EventNvmCtxChanged commandsNvmCtxChanged )
LoRaMacCommandStatus_t LoRaMacCommandsInit( LoRaMacCommandsNvmEvent commandsNvmCtxChanged )
{
// Initialize with default
memset1( (uint8_t*)&NvmCtx, 0, sizeof( NvmCtx ) );
memset1( ( uint8_t* )&NvmCtx, 0, sizeof( NvmCtx ) );
linkedListInit( &NvmCtx.MacCommandList );
LinkedListInit( &NvmCtx.MacCommandList );
// Assign callback
CommandsNvmCtxChanged = commandsNvmCtxChanged;
@@ -326,7 +317,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsRestoreNvmCtx( void* commandsNvmCtx )
// Restore module context
if( commandsNvmCtx != NULL )
{
memcpy1( ( uint8_t* ) &NvmCtx, ( uint8_t* ) commandsNvmCtx, sizeof( NvmCtx ) );
memcpy1( ( uint8_t* )&NvmCtx, ( uint8_t* )commandsNvmCtx, sizeof( NvmCtx ) );
return LORAMAC_COMMANDS_SUCCESS;
}
else
@@ -341,24 +332,24 @@ void* LoRaMacCommandsGetNvmCtx( size_t* commandsNvmCtxSize )
return &NvmCtx;
}
LoRaMacCommandStatus_t LoRaMacCommandsAddCmd( uint8_t cid, uint8_t* payload, size_t payloadSize )
LoRaMacCommandStatus_t LoRaMacCommandsAddCmd( uint8_t cid, uint8_t* payload, size_t payloadSize )
{
if( payload == 0 )
if( payload == NULL )
{
return LORAMAC_COMMANDS_ERROR_NPE;
}
MacCommand_t* newCmd;
// Allocate a memory slot
newCmd = mallocNewMacCommandSlot( );
newCmd = MallocNewMacCommandSlot( );
if( newCmd == 0 )
if( newCmd == NULL )
{
return LORAMAC_COMMANDS_ERROR_MEMORY;
}
// Add it to the list of Mac commands
if( linkedListAdd( &NvmCtx.MacCommandList, newCmd ) == false )
if( LinkedListAdd( &NvmCtx.MacCommandList, newCmd ) == false )
{
return LORAMAC_COMMANDS_ERROR;
}
@@ -366,7 +357,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsAddCmd( uint8_t cid, uint8_t* payload, si
// Set Values
newCmd->CID = cid;
newCmd->PayloadSize = payloadSize;
memcpy1( ( uint8_t* ) newCmd->Payload, payload, payloadSize );
memcpy1( ( uint8_t* )newCmd->Payload, payload, payloadSize );
newCmd->IsSticky = IsSticky( cid );
NvmCtx.SerializedCmdsSize += ( CID_FIELD_SIZE + payloadSize );
@@ -384,7 +375,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveCmd( MacCommand_t* macCmd )
}
// Remove the Mac command element from MacCommandList
if( linkedListRemove( &NvmCtx.MacCommandList, macCmd ) == false )
if( LinkedListRemove( &NvmCtx.MacCommandList, macCmd ) == false )
{
return LORAMAC_COMMANDS_ERROR_CMD_NOT_FOUND;
}
@@ -392,7 +383,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveCmd( MacCommand_t* macCmd )
NvmCtx.SerializedCmdsSize -= ( CID_FIELD_SIZE + macCmd->PayloadSize );
// Free the MacCommand Slot
if( freeMacCommandSlot( macCmd ) == false )
if( FreeMacCommandSlot( macCmd ) == false )
{
return LORAMAC_COMMANDS_ERROR;
}
@@ -410,19 +401,19 @@ LoRaMacCommandStatus_t LoRaMacCommandsGetCmd( uint8_t cid, MacCommand_t** macCmd
curElement = NvmCtx.MacCommandList.First;
// Loop through all elements until we find the element with the given CID
while(curElement && ( curElement->CID != cid ) )
while( ( curElement != NULL ) && ( curElement->CID != cid ) )
{
curElement = curElement->Next;
}
// Update the pointer anyway
*macCmd = curElement;
// Handle error in case if we reached the end without finding it.
if( curElement == NULL )
{
return LORAMAC_COMMANDS_ERROR_CMD_NOT_FOUND;
}
*macCmd = curElement;
return LORAMAC_COMMANDS_SUCCESS;
}
@@ -435,7 +426,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveNoneStickyCmds( void )
curElement = NvmCtx.MacCommandList.First;
// Loop through all elements
while( curElement )
while( curElement != NULL )
{
if( curElement->IsSticky == false )
{
@@ -466,16 +457,9 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveStickyAnsCmds( void )
while( curElement != NULL )
{
nexElement = curElement->Next;
if( curElement->IsSticky == true )
if( IsSticky( curElement->CID ) == true )
{
for( uint8_t i = 0; i < sizeof( CIDsStickyAnsCmds ); i++)
{
if( curElement->CID == CIDsStickyAnsCmds[i] )
{
LoRaMacCommandsRemoveCmd( curElement );
break;
}
}
LoRaMacCommandsRemoveCmd( curElement );
}
curElement = nexElement;
}
@@ -493,28 +477,28 @@ LoRaMacCommandStatus_t LoRaMacCommandsGetSizeSerializedCmds( size_t* size )
}
*size = NvmCtx.SerializedCmdsSize;
return LORAMAC_COMMANDS_SUCCESS;
}
LoRaMacCommandStatus_t LoRaMacCommandsSerializeCmds( size_t availableSize, size_t* effectiveSize, uint8_t* buffer )
LoRaMacCommandStatus_t LoRaMacCommandsSerializeCmds( size_t availableSize, size_t* effectiveSize, uint8_t* buffer )
{
MacCommand_t* curElement = NvmCtx.MacCommandList.First;
MacCommand_t* nextElement;
uint8_t itr = 0;
if( ( buffer == NULL ) || ( effectiveSize == NULL ) )
{
return LORAMAC_COMMANDS_ERROR_NPE;
}
MacCommand_t* curElement;
curElement = NvmCtx.MacCommandList.First;
uint8_t itr = 0;
// Loop through all elements
while( curElement )
// Loop through all elements which fits into the buffer
while( curElement != NULL )
{
// If the next MAC command still fits into the buffer, add it.
if( ( availableSize - itr ) >= ( CID_FIELD_SIZE + curElement->PayloadSize ) )
{
buffer[itr++] = curElement->CID;
memcpy1( &buffer[itr], curElement->Payload, curElement->PayloadSize );
itr = itr + curElement->PayloadSize;
itr += curElement->PayloadSize;
}
else
{
@@ -523,6 +507,18 @@ LoRaMacCommandStatus_t LoRaMacCommandsSerializeCmds( size_t availableSize, size_
curElement = curElement->Next;
}
// Remove all commands which do not fit into the buffer
while( curElement != NULL )
{
// Store the next element before removing the current one
nextElement = curElement->Next;
LoRaMacCommandsRemoveCmd( curElement );
curElement = nextElement;
}
// Fetch the effective size of the mac commands
LoRaMacCommandsGetSizeSerializedCmds( effectiveSize );
return LORAMAC_COMMANDS_SUCCESS;
}
@@ -538,7 +534,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsStickyCmdsPending( bool* cmdsPending )
*cmdsPending = false;
// Loop through all elements
while( curElement )
while( curElement != NULL )
{
if( curElement->IsSticky == true )
{
@@ -551,3 +547,103 @@ LoRaMacCommandStatus_t LoRaMacCommandsStickyCmdsPending( bool* cmdsPending )
return LORAMAC_COMMANDS_SUCCESS;
}
uint8_t LoRaMacCommandsGetCmdSize( uint8_t cid )
{
uint8_t cidSize = 0;
// Decode Frame MAC commands
switch( cid )
{
case SRV_MAC_LINK_CHECK_ANS:
{
// cid + Margin + GwCnt
cidSize = 3;
break;
}
case SRV_MAC_LINK_ADR_REQ:
{
// cid + DataRate_TXPower + ChMask (2) + Redundancy
cidSize = 5;
break;
}
case SRV_MAC_DUTY_CYCLE_REQ:
{
// cid + DutyCyclePL
cidSize = 2;
break;
}
case SRV_MAC_RX_PARAM_SETUP_REQ:
{
// cid + DLsettings + Frequency (3)
cidSize = 5;
break;
}
case SRV_MAC_DEV_STATUS_REQ:
{
// cid
cidSize = 1;
break;
}
case SRV_MAC_NEW_CHANNEL_REQ:
{
// cid + ChIndex + Frequency (3) + DrRange
cidSize = 6;
break;
}
case SRV_MAC_RX_TIMING_SETUP_REQ:
{
// cid + Settings
cidSize = 2;
break;
}
case SRV_MAC_TX_PARAM_SETUP_REQ:
{
// cid + EIRP_DwellTime
cidSize = 2;
break;
}
case SRV_MAC_DL_CHANNEL_REQ:
{
// cid + ChIndex + Frequency (3)
cidSize = 5;
break;
}
case SRV_MAC_DEVICE_TIME_ANS:
{
// cid + Seconds (4) + Fractional seconds (1)
cidSize = 6;
break;
}
case SRV_MAC_PING_SLOT_INFO_ANS:
{
// cid
cidSize = 1;
break;
}
case SRV_MAC_PING_SLOT_CHANNEL_REQ:
{
// cid + Frequency (3) + DR
cidSize = 5;
break;
}
case SRV_MAC_BEACON_TIMING_ANS:
{
// cid + TimingDelay (2) + Channel
cidSize = 4;
break;
}
case SRV_MAC_BEACON_FREQ_REQ:
{
// cid + Frequency (3)
cidSize = 4;
break;
}
default:
{
// Unknown command. ABORT MAC commands processing
break;
}
}
return cidSize;
}