If a client sends a unix datagram without having bound the socket to an
address, the recvfrom in the server will return an empty-path,
smaller-than-normal (16 bytes instead of 106) sockaddr_un on OpenBSD,
which netcat does not check and uses in a subsequent connect(), which is
invalid:

  $ ./nc -vnNUul /tmp/a & (sleep .2; ./dgramtest /tmp/a)
  nc: connect: Invalid argument <-- server dying

(dgramtest sends a unix datagram message without binding its socket.)

Here's the failing connect:

        [...]
        } else if (uflag && !kflag) {
                /*
                 * For UDP and not -k, we will use recvfrom()
                 * initially to wait for a caller, then use
                 * the regular functions to talk to the caller.
                 */
                int rv;
                char buf[2048];
                struct sockaddr_storage z;

                len = sizeof(z);
                rv = recvfrom(s, buf, sizeof(buf), MSG_PEEK,
                    (struct sockaddr *)&z, &len);
                if (rv == -1)
                        err(1, "recvfrom");

                rv = connect(s, (struct sockaddr *)&z, len);
                if (rv == -1)
                        err(1, "connect");

                if (vflag)
        [...]

It seems this connect is done in order to have a single generic
implementation of the readwrite loop, but given that it's not an error
to send messages on an unbound datagram socket it seems particularly
lame to fail here.  Perhaps in this case the loop could still be entered
provided the "-d" flag was given (no stdin, no sending functionality).

Cheers.

Reply via email to