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.

CC2538: Issues with ZCL APIs in ZStack 3.0.1

Part Number: CC2538
Other Parts Discussed in Thread: Z-STACK

Hi,

I'm a PhD student and currently learning Z-Stack implementation. Recently, I find some ZCL API calls could be crashed with random data. I'm using Z-Stack 3.0.1 and CC2538 and IAR Workbench for debugging. The project I'm using is the sample project GenericApp.

First, I use some fuzzing tool to generate ZCL command message based on its specification, including some random data in its payload. The ZCL header is exactly follow the spec. And for attribute value, I use some random data. The I verify them in CC2538. The functions I found problems are zclParseInWrite and zcl_HandleExternal.

I've attached more details including my source codes, log files and sniff data. I suppose Z-Stack could handle random payload/malformed data, like returning error codes, since attacker may manipulate the packet. Could you please help me verify if something wrong with the API calls?

Thank you so much!

crash.zip 

  • Hi,

    Thanks for sharing your findings on this matter.

    Have you already looked over known issues here: https://e2e.ti.com/support/wireless-connectivity/zigbee-and-thread/f/158/t/902631

    If possible, I would recommend moving to Z-Stack 3.0.2.



    Regards,
    Toby

  • Hi Toby,

    Thanks for quick response. I've looked the known issues page. Actually what I found are not the functions mentioned in that page. Especially the issue of zcl_HandleExternal() since I didn't define the macro BDB_REPORTING. So I want know if what I found are new ones, or if I set up something wrong that may lead such errors.

    Also, I compare the codes with Z-Stack 3.0.2. They are the same for the APIs I found. I would very appreciate if you can verify them as well.

    Thanks,

    Mengfei

  • Thank you for confirming.

    After looking through the contents you attached, here's what I think is happening:

    • When ZED receives "Write Attributes No Response", and zclParseCmd (which is zclParseInWriteCmd for ZCL_CMD_WRITE_NO_RSP, as defined in zclCmdTable):
      • Looks like you've made it so that the ZED will receive all commands, then pass the foundation ones to zcl_TaskID (in zclGenericApp_event_loop).
      • Note that later, zclGenericApp_event_loop actually frees the allocated memory (osal_msg_deallocate( (uint8 *)MSGpkt )).
      • So it seems like zcl_event_loop (zcl_TaskID) will not have this in order to parse properly (zclParseInWriteCmd ).
      • The fix here, could be: in zclGenericApp_event_loop, allocate memory (say pCpy), then copy MSGpkt to that pCpy, and finally osal_msg_send(zcl_TaskID, (uint8 *)pCpy).
    • When ZED receives "Read Reporting Configuration Response", and it seems to hang:
      • zclGenericApp_event_loop passes this to zcl_TaskID (zcl_event_loop)
      • But the handler for ZCL_CMD_READ_REPORT_CFG_RSP is zcl_HandleExternal (as defined in zclCmdTable).
      • It seems like zcl_HandleExternal will then pass this to the registered handler for this endpoint (probably ends up passing it to zclGenericApp_TaskID/zclGenericApp_event_loop).
      • This results in both tasks passing the message back and forth, resulting in an infinite loop of sorts.
      • The fix here, could be to define a different handler for this command (or register a different endpoint/task).

  • Thank you for your confirmation and the fix solution. But I still have some confusions.

    1. For parsing write command, the root cause is the improper memory deallocation in zclGenericApp_event_loop. This is actually the user's software application which is customized by different user. So it's not an implementation fault in ZCL library, right?

    And I'm wondering why not deallocate the memory until ZCL completes the processing. Because the message processing is asynchronized  among different event loop?

    2. So zcl_HandleExternal actually doesn't process some specific commands like ZCL_CMD_READ_REPORT_CFG_RSP, it only passes the message to the upper level application, right? The root cause is the misconfiguration from the upper level application, right? 

    If the user wants to enable the reporting feature related to such command, it's better to define their own handlers instead of using zcl_HandleExternal, right? I'm wondering why not discard such message after some attempts, or send an error back to the user for unsuccessful handling.

    3. I notice in the sample project, there is a function zclGenericApp_ProcessIncomingMsg() to process ZCL foundation messages in the application-level. If ZCL library has already provided corresponding APIs, why the user needs to process them rather than let ZCL handles, just like what I did to forward message to ZCL? Also, for the command ZCL_CMD_READ_REPORT_CFG_RSP could be handled by BDB in that function. Does it mean the setup in zclCmdTable is useless, or overwritten?

    Anyway, your explanation give me many ideas to help me understand the Zigbee protocol. Thank you again Toby! 

  • Mengfei Ren said:
    1. For parsing write command, the root cause is the improper memory deallocation in zclGenericApp_event_loop. This is actually the user's software application which is customized by different user. So it's not an implementation fault in ZCL library, right?

    No, I don't believe it's an implementation fault in ZCL library.

    Mengfei Ren said:
    And I'm wondering why not deallocate the memory until ZCL completes the processing. Because the message processing is asynchronized among different event loop?

    Yes, this will be passed to the osal scheduler which holds the message for specific task (it assumes that the message body points to allocated memory).

    Mengfei Ren said:
    2. So zcl_HandleExternal actually doesn't process some specific commands like ZCL_CMD_READ_REPORT_CFG_RSP, it only passes the message to the upper level application, right? The root cause is the misconfiguration from the upper level application, right?

    Correct, some commands relate to scope of application.

    Mengfei Ren said:
    If the user wants to enable the reporting feature related to such command, it's better to define their own handlers instead of using zcl_HandleExternal, right? I'm wondering why not discard such message after some attempts, or send an error back to the user for unsuccessful handling.

    Yes, they should handle it according to their application.
    Usually ZCL will pass relevant messages to application to handle (e.g. zcl_HandleExternal), and not the other way around. The application will mostly be initiating ZCL commands.

    Mengfei Ren said:
    3. I notice in the sample project, there is a function zclGenericApp_ProcessIncomingMsg() to process ZCL foundation messages in the application-level. If ZCL library has already provided corresponding APIs, why the user needs to process them rather than let ZCL handles, just like what I did to forward message to ZCL? Also, for the command ZCL_CMD_READ_REPORT_CFG_RSP could be handled by BDB in that function. Does it mean the setup in zclCmdTable is useless, or overwritten?

    The incoming ZCL commands could be for different endpoints on this device, so ZCL module will send this message to the registered handler for that endpoint. ZCL module will perform any mandatory actions (e.g. see zclProcessInWriteCmd for Write Attributes command, it will write the attribute accordingly). Handling of, for example, response commands, is handled per endpoint/task and is up to the application.