Subject: Bug#515: [X2Go-Dev] [X2Go-User] "connectedHost" variable contains wrong IP, reason unknown

From: Mihai Moldovan <[email-masked]>
Date: Sat, 14 Jun 2014 03:40:07 +0200

Basically, the addresses Sebastien has seen were "nothing more" than
uninitialized memory.

The underlaying issue was that accept() wants a socklen_t *addrlen parameter.
The original code created a size_t variable to store the size of the sockaddr
structure where information like the IP address is to be written. This value has
been, correctly, set to 16. It was then casted to (socklen_t) and given to accept().

The problem, however, is that socklen_t is defined as a 4 byte integer, while
size_t is at least 8 bytes wide on ppc64. (I highly recommend reading man 2
accept and the in the man page included Linus Torvald rant on that matter!)

This is "not a big deal" on little endian machines, as casting size_t to
socklen_t there will only cut the upper 4 bytes off and leave you with the lower
4 bytes -- which is just fine, as struct sockaddr isn't bigger than 2^32-1 bytes
anyway. 16 stays 16 in that case.

Doing the same thing on big endian machines, however, cuts the lower 4 bytes off
and leaves you with the upper 4 bytes. As the original value was "16", the upper
4 bytes were all zero.

Thus, zero was passed as the addrlen parameter to accept().

As the addrlen parameter defines how many bytes may be written to the sockaddr
structure given to accept(), the function didn't even touch addr. Hence, addr
was left in its original, un-initialized state.

It was an endianness issue after all, but not exactly where anyone would have
expected it.

The fix is trivial -- don't use size_t as the type of the addrlen variable, but
socklen_t, which will also remove the need of casting.

Mike: I hope the patch applies fine. I have quiltimported all other patches
before, so my patch is based on the patched nx-libs repository.
diff --git a/nxcomp/Loop.cpp b/nxcomp/Loop.cpp
index c9617c3..955be85 100644
--- a/nxcomp/Loop.cpp
+++ b/nxcomp/Loop.cpp
@@ -6854,9 +6854,9 @@ int WaitForRemote(int portNum)
     {
       sockaddr_in newAddr;
 
-      size_t addrLen = sizeof(sockaddr_in);
+      socklen_t addrLen = sizeof(sockaddr_in);
 
-      newFD = accept(proxyFD, (sockaddr *) &newAddr, (socklen_t *) &addrLen);
+      newFD = accept(proxyFD, (sockaddr *) &newAddr, &addrLen);
 
       if (newFD == -1)
       {