Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debug.Assert when using ReceiveFrom on UnixDomainSocket #78448

Closed
wfurt opened this issue Nov 16, 2022 · 1 comment · Fixed by #90086
Closed

Debug.Assert when using ReceiveFrom on UnixDomainSocket #78448

wfurt opened this issue Nov 16, 2022 · 1 comment · Fixed by #90086
Assignees
Milestone

Comments

@wfurt
Copy link
Member

wfurt commented Nov 16, 2022

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.

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Nov 16, 2022
@ghost
Copy link

ghost commented Nov 16, 2022

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

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.

Author: wfurt
Assignees: -
Labels:

area-System.Net.Sockets

Milestone: -

@wfurt wfurt self-assigned this Nov 16, 2022
@wfurt wfurt added this to the 8.0.0 milestone Nov 16, 2022
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Nov 16, 2022
@karelz karelz modified the milestones: 8.0.0, Future Jun 9, 2023
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Aug 8, 2023
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Aug 8, 2023
@karelz karelz modified the milestones: Future, 8.0.0 Aug 10, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Sep 9, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants