buglwIP - A Lightweight TCP/IP stack - Bugs: bug #57445, LWIP_NETCONN_FULLDUPLEX: Assertion...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #57445: LWIP_NETCONN_FULLDUPLEX: Assertion failed: sockets[i].select_waiting == 0

Submitter:  Patrick Schlangen <pschlang>
Submitted:  Thu 19 Dec 2019 09:42:42 AM UTC
   
 
Category:  sockets/netconn Severity:  3 - Normal
Item Group:  None Status:  Fixed
Privacy:  Public Assigned to:  goldsimon
Open/Closed:  Closed Planned Release:  None
lwIP version:  git head

Thu 30 Jan 2020 08:05:45 PM UTC, comment #1: 

Applied, thanks for the patch.

Simon Goldschmidt <goldsimon>
Group administrator
Thu 19 Dec 2019 09:42:42 AM UTC, original submission:  

Hi,

I've discovered a possible issue with lwip_select() in LWIP_NETCONN_FULLDUPLEX mode.

When closing a socket which is being lwip_select()ed on from another task/thread, the socket might end up in a state where it is closed but select_waiting is not decremented properly. This will trigger the assertion "sockets[i].select_waiting == 0" when re-allocating that socket.

I'm trying to explain the failure mechanism:

1. A thread calls lwip_select() to wait for events on a specific socket

2. lwip_select() will increment the used count for each socket via lwip_select_inc_sockets_used() to ensure it's not freed during the select process

3. After increasing the select_waiting for the socket but before decrementing it again (i.e. while waiting for events), the socket is closed from another thread/task. Since the socket is still in use by lwip_select(), fd_free_pending will be set.

4. In lwip_select(), the loop to decrease select_waiting is entered. In the loop, tryget_socket_unconn_locked is used to retrieve the socket structure. For the socket closed in (3), tryget_socket_unconn_locked will return NULL because fd_free_pending is set (checked in sock_inc_used_locked).  Since tryget_socket_unconn_locked returned NULL, lwip_select() will correctly set nready to -1 an errno to EBADF, but it never decrements select_waiting for that socket.

5. lwip_select_dec_sockets_used() is used to decrement the used count before returning -1 from lwip_select(). The used count of the closed socket will become 0 and the socket is actually freed, but select_waiting is still 1.

6. Later, when re-using the socket structure in alloc_socket(), "sockets[i].select_waiting == 0" assertion fails.

Is this an issue in lwIP or am I just using it in a non-supported way?

I've prepared a small patch which fixes the problem in my tests. Since I'm not an expert on lwIP internals, I'd appreciate if somebody could double-check if the fix is valid.

Best,

Patrick

Patrick Schlangen <pschlang>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attached Files

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by goldsimon (Posted a comment)
  • -email is unavailable- added by pschlang (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

     

    Follow 4 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2020-01-30 goldsimon StatusNone Fixed
        Assigned toNone goldsimon
        Open/ClosedOpen Closed
    2019-12-19 pschlang Attached File- Added 0001-Fix-select_waiting-not-being-decremented-for-sockets.patch, #48091

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code