Skip to content

Debug.Assert when using ReceiveFrom on UnixDomainSocket #78448

Closed
@wfurt

Description

@wfurt

I was adding new test like

            using (Socket server = new Socket(AddressFamily.Unix, SocketType.Dgram, ProtocolType.Unspecified))
            {
                server.Bind(new UnixDomainSocketEndPoint(serverAddress));
                using (Socket client = new Socket(AddressFamily.Unix, SocketType.Dgram, ProtocolType.Unspecified))
                {
                    byte[] data = Encoding.ASCII.GetBytes(nameof(UnixDomainSocketEndPoint_SendToReceiveFrom_CorrectEndPoint));
                    // Bind the client.
                    client.Bind(new UnixDomainSocketEndPoint(clientAddress));

                    var sender = new UnixDomainSocketEndPoint(GetRandomNonExistingFilePath());
                    EndPoint senderRemote = (EndPoint)sender;
                    client.SendTo(data, server.LocalEndPoint);

                    byte[] buffer = new byte[data.Length * 2];
                    int receivedBytes = server.ReceiveFrom(buffer, ref senderRemote);
                }
            }

and it will produce core with

   Starting:    System.Net.Sockets.Tests (parallel test collections = off, max threads = 4)
      System.Net.Sockets.Tests.UnixDomainSocketTest.UnixDomainSocketEndPoint_SendToReceiveFrom_CorrectEndPoint(abstractAddress: False) [STARTING]
  dotnet: /home/furt/github/wfurt-runtime/src/native/libs/System.Native/pal_networking.c:1407: int32_t SystemNative_ReceiveMessage(intptr_t, MessageHeader *, int32_t, int64_t *): Assertion `(int32_t)header.msg_namelen <= messageHeader->SocketAddressLen' failed.
  /home/furt/github/wfurt-runtime/artifacts/bin/System.Net.Sockets.Tests/Debug/net7.0-unix/RunTests.sh: line 168: 79756 Aborted                 (core dumped) "$RUNTIME_PATH/dotnet" exec --runtimeconfig System.Net.Sockets.Tests.runtimeconfig.json --

While sockaddr_un has fixed size the actual path can vary

          struct sockaddr_un {
               sa_family_t sun_family;               /* AF_UNIX */
               char        sun_path[108];            /* Pathname */
           };

We seems to serialize only the actual size of the EndPoint so unless caller always creates string with maximum platform size they may have problems. (production code truncates the address)

Since the EndPoint is passed in as ref to be filled in it should not matter what the endpoint was. It would be nice if one could simply create empty UnixDomainSocketEndPoint from string.Empty but that fails in constructor.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions