cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 LWIP : IP stack stop working during TCP port scanning from vulnerabilities test tool

FDESS.2
Associate II

Hello,

We have implemented LWIP with FreeRTOS on a STM32F407VE with a LAN8720A PHY.

Everything worked fine until our client submit our card to a IP vulnerabilities tester : during the test the card stop responding to ping.

The test consists to try a connection on random TCP ports, about hundreds time each seconds... Please see below wireshark screen shot.

0690X00000ARLhHQAX.png

By looking deeply in the source code, it appears that ETH_IRQHandler() is no longer generated in that case. So ethernetif.c/ethernetif_input() stay blocked on osSemaphoreWait() call indefintly.

All code was generated with STM32cubeMX (5.3)/Atollic TRuestudio with RTOS 10.0.1 and LwIP 2.0.3.

I have found a workaroud by adding a timeout in osSemaphoreWait() of ethernetif_input() loop. When timeout occurs low_level_reinit() is called and everything run well.

void ethernetif_input( void const * argument ) 
{
  struct pbuf *p;
  struct netif *netif = (struct netif *) argument;
  
  for( ;; )
  {
    if (osSemaphoreWait( s_xSemaphore, 5000/*TIME_WAITING_FOR_INPUT*/)==osOK)
    {
      do
      {   
        p = low_level_input( netif );
        if   (p != NULL)
        {
          if (netif->input( p, netif) != ERR_OK )
          {
            pbuf_free(p);
          }
        }
      } while(p!=NULL);
    }
    else
    {
      if (netif_is_link_up(netif) == 1)
      {
          low_level_init(netif);
      }
    }
  }
}

 I also modified low_level_init() to avoid multiple creation of semaphore and thread:

static void low_level_init(struct netif *netif)
{
......
 
 if (s_xSemaphore == NULL)
	{
	  osSemaphoreDef(SEM);
	  s_xSemaphore = osSemaphoreCreate(osSemaphore(SEM) , 1 );
 
	/* create the task that handles the ETH_MAC */
	  osThreadDef(EthIf, ethernetif_input, osPriorityRealtime, 0, INTERFACE_THREAD_STACK_SIZE);
	  osThreadCreate (osThread(EthIf), netif);
	}
 
....
}

I wonder if there is a better way to do or if I have done a mistake elsewhere ?

I thank you for your help,

Fabien.

9 REPLIES 9
Nettok
Associate II

edit: THIS IS WRONG. I am leaving it so you can see what didn't really worked 🙂

I also stumbled upon this issue, as anyone else who has used the default CubeMX code.

My attempted solution to this ethernet deadlock was this :

memset(&attributes, 0x0, sizeof(osThreadAttr_t));
  attributes.name = "EthIf";
  attributes.stack_size = INTERFACE_THREAD_STACK_SIZE;
  attributes.priority = osPriorityNormal;         //  <--- I  lowered the priority of this thread
  osThreadNew(ethernetif_input, netif, &attributes);

Though it only seems to delay the issue.

Another change that seems to have helped is to enable the following advanced parameter:

LWIP_MPU_COMPATIBLE

0693W000000WIzkQAG.png

Piranha
Chief II
Nettok
Associate II

Thanks for the links, I'll take a look and see if I can still improve things in my code.

Note that I was already using the latest CubeMX version with this specific issue fix.

I left a test running overnight with my proposed changes, and it hanged again after some hours. At least it is not minutes though.

Piranha
Chief II

If you want to make it really working, then disable link detection thread, disable DHCP, set manual IP address and test if that helps. If it does, then you have to fix those parts of code. There are hints and links for this in my topic.

RZasa.1
Associate III

I had exactly the same problem as OP while using already "fixed" version of STM32CubeIDE (Version: 1.5.1) + NUCLEO F767ZI. While investigating this and other issues in my program using vTaskList() diagnostic tool I have discovered that code generated by STM32CubeIDE simply set too low stack size for "EthIf" thread:

File Name     : ethernetif.c

#define INTERFACE_THREAD_STACK_SIZE ( 350 )

When I set it to 500 everything works fine and I wasn't able to crash it despite trying hard.

I did not see an option to set it from STM32CubeIDE.

Enable compiler optimization up to O3/Ofast levels with LTO (Link Time Optimization), run an iPerf2 test, and look how it falls apart instantly. 😉

This was the only method that worked for me, thanks!

I also got stuck on the osSemaphoreAcquire(s_xSemaphore, TIME_WAITING_FOR_INPUT) line on the new version of STM32CubeIDE, and after increasing INTERFACE_THREAD_STACK_SIZE to 700, my code that used to break after 2-3 seconds has been running flawlessly for around 10 minutes now

Same problem got stuck on  osSemaphoreAcquire(s_xSemaphore, TIME_WAITING_FOR_INPUT) After increasing INTERFACE_THREAD_STACK_SIZE size, Now it running without stuck.