Hi there,
I run into an issue NDK_accept() returning EINVAL accidentally despite it shouldn't.
I think I found a bug in NDK implementation. I debugged it in v2.25.0.9, the code of current c2.25.1.11 looks the same (stack/fdt/socket.c):
SOCKET NDK_accept( SOCKET s, PSA pName, int *plen ) { FILEDESC *pfd = (FILEDESC *)s; ... /* If there's a name, there must be a valid length */ if (pName && (!plen || (pName->sa_family == AF_INET && *plen < sizeof(SA_IN)) #ifdef _INCLUDE_IPv6_CODE || (pName->sa_family == AF_INET6 && *plen < sizeof(SA_IN6)) #endif )) { error = EINVAL; goto accept_error; } ... /* Get the connected address */ #ifdef _INCLUDE_IPv6_CODE if (pfd->Type == HTYPE_SOCK6) { if (pName) Sock6GetName(pfdnew, 0, pName); if (plen) *plen = sizeof(SA_IN6); } else #endif { if (pName) SockGetName(pfdnew, 0, pName); if (plen) *plen = sizeof(SA_IN); } ... }
The code checks pName->sa_family to decide if it expects IPv4 or IPv6 and thus checks if the size of the struct is sufficient for IPv4 or IPv6 either.
The documentation (spru524j) clearly says "The argument addr is a result parameter that is filled in with the address of the connecting entity as known to the communications layer." So the code should not check its contents! As I called NDK_accept() with pName as a reference to an uninitialized local var NDK_accept() checked some value in the stack. Depending on the program flow history pName->sa_family happened to be AF_INET6 (10). As I am working with IPv4 it complained about the size of the struct being less than sizeof(SA_IN6) and returned unexpectedly with EINVAL.
Since NDK_accept() decides depending on pfd->Type == HTYPE_SOCK6 if it wants to fill a SA_IN6 or SA_IN struct I think it should check pfd->Type too to decide which size it expects.
I changed
if (pName && (!plen || (pName->sa_family == AF_INET && *plen < sizeof(SA_IN)) #ifdef _INCLUDE_IPv6_CODE || (pName->sa_family == AF_INET6 && *plen < sizeof(SA_IN6)) #endif ))
to
if (pName && (!plen || ((pfd->Type == HTYPE_SOCK) && *plen < sizeof(SA_IN)) #ifdef _INCLUDE_IPv6_CODE || ((pfd->Type == HTYPE_SOCK6) && *plen < sizeof(SA_IN6)) #endif )) and now it works fine for me.
May be you want to accept this bugfix ...
Best regards,
Lars