netcat: unix datagram listener dies if peer is unbound

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

netcat: unix datagram listener dies if peer is unbound

astian
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 | Threaded
Open this post in threaded view
|

Re: netcat: unix datagram listener dies if peer is unbound

astian
astian:
> 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,

FYI, after testing a bit, it seems that other kernels will also return a
structure size smaller than sizeof(struct sockaddr_un) in some cases,
even successful cases.  So maybe I shouldn't consider such occurrence
"abnormal".  This is relevant for the ugly "[unknown address]" special
case in the diff I sent in the bugs@ thread "netcat: fix
report_sock-related bugs".

> which netcat does not check and uses in a subsequent connect(), which is
> invalid: