[Bug 191586] New: FreeBSD doesn't validate negative edgecases in bind(2)/connect(2)/listen(2) like POSIX requires

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Thu Jul 3 19:03:35 UTC 2014


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=191586

            Bug ID: 191586
           Summary: FreeBSD doesn't validate negative edgecases in
                    bind(2)/connect(2)/listen(2) like POSIX requires
           Product: Base System
           Version: 11.0-CURRENT
          Hardware: Any
                OS: Any
            Status: Needs Triage
          Severity: Affects Only Me
          Priority: ---
         Component: standards
          Assignee: freebsd-standards at FreeBSD.org
          Reporter: yaneurabeya at gmail.com

POSIX specifies certain requirements for validating sa_family with bind(2) and
connect(2):

>From bind(2):

[EAFNOSUPPORT]
    The specified address is not a valid address for the address family of the
specified socket.

...

[EINVAL]
    The address_len argument is not a valid length for the address family.

>From connect [2]:

[EINVAL]
    The address_len argument is not a valid length for the address family; or
invalid address family in the sockaddr structure.

>From listen [3]:

[EDESTADDRREQ]
    The socket is not bound to a local address, and the protocol does not
support listening on an unbound socket.

FreeBSD 10/stable does not appear to be conforming to POSIX:
- bind(2) doesn't appear to be validating the sa_family member at all (it
doesn't set errno to either EAFNOSUPPORT or EINVAL).
- connect(2)'s not handling EINVAL properly, but the issue is being caught with
EAFNOSUPPORT .
- listen(2)'s not handling EDESTADDRREQ.

I haven't tested out a kernel built INET, INET6, or SCTP support compiled out
to ensure that these cases would be caught properly.

1. http://pubs.opengroup.org/onlinepubs/009695399/functions/bind.html
2. http://pubs.opengroup.org/onlinepubs/009695399/functions/connect.html
3. http://pubs.opengroup.org/onlinepubs/009695399/functions/listen.html

% uname -a
FreeBSD freebsd-10-x64.localdomain 10.0-STABLE FreeBSD 10.0-STABLE #2
r267849+810c962(stable/10): Wed Jun 25 14:23:41 PDT 2014    
root at freebsd-10-x64.localdomain:/usr/obj/usr/src/sys/GENERIC-WITHOUT-WITNESS 
amd64
% sysctl -Na | grep -q sctp && echo "has SCTP"
has SCTP
% sysctl kern.features. | grep 'inet'
kern.features.inet: 1
kern.features.inet6: 1
% cat /root/test_bogus_sa_family.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int
main(void)
{
        struct sockaddr_in sai;
        int sock;

        sock = socket(AF_INET, SOCK_STREAM, 0);

        memset(&sai, 0, sizeof(sai));
        memset(&sai, 0, sizeof(sai));

        sai.sin_family = AF_MAX + 10;
        sai.sin_addr.s_addr = INADDR_ANY;
        sai.sin_port = 42000;

        if (bind(sock, (struct sockaddr*)&sai, sizeof(sai)) == 0) {
                warnx("bind did not fail with invalid sin_family as expected");
                if (listen(sock, 1) == 0) {
                        warnx("and is now listening for connections on an
invalid address family!? (netstat output follows)");
                        system("netstat -a | grep LISTEN");
                } else
                        warn("but did fail when listen was called");
        } else if (errno != EAFNOSUPPORT)
                warn("bind did not fail with EAFNOSUPPORT");
        else
                printf("bind test passed");

        close(sock);

        sock = socket(AF_INET, SOCK_STREAM, 0);

        if (connect(sock, (struct sockaddr*)&sai, sizeof(sai)) == 0)
                warnx("connect did not fail with invalid sin_family as
expected");
        else if (errno != EINVAL)
                warn("connect did not fail with EINVAL");
        else
                printf("connect test passed");

        close(sock);

        return (0);
}
% /root/test_bogus_sa_family
test_bogus_sa_family: bind did not fail with invalid sin_family as expected
test_bogus_sa_family: and is now listening for connections on an invalid
address family!? (netstat output follows)
tcp4       0      0 *.4260                 *.*                    LISTEN
tcp4       0      0 localhost.smtp         *.*                    LISTEN
tcp4       0      0 *.ssh                  *.*                    LISTEN
tcp6       0      0 *.ssh                  *.*                    LISTEN
tcp6       0      0 *.nfsd                 *.*                    LISTEN
tcp4       0      0 *.nfsd                 *.*                    LISTEN
tcp4       0      0 *.mecomm               *.*                    LISTEN
tcp6       0      0 *.mecomm               *.*                    LISTEN
tcp4       0      0 *.sunrpc               *.*                    LISTEN
tcp6       0      0 *.sunrpc               *.*                    LISTEN
test_bogus_sa_family: connect did not fail with EINVAL: Address family not
supported by protocol family

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-standards mailing list