NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/53775: bind(2) may inaccurately return EADDRNOTAVAIL



>Number:         53775
>Category:       kern
>Synopsis:       bind(2) may inaccurately return EADDRNOTAVAIL
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Dec 11 09:45:00 +0000 2018
>Originator:     he%NetBSD.org@localhost
>Release:        NetBSD 8.0_STABLE
>Organization:
	I try...
>Environment:
System: NetBSD smistad.uninett.no 8.0_STABLE NetBSD 8.0_STABLE (GENERIC) #0: Sun Aug 5 00:07:14 CEST 2018 he%smistad.uninett.no@localhost:/usr/obj/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:
	The bind(2) system call may return EADDRNOTAVAIL also in cases
	where it more precisely should return EADDRINUSE.

	This was uncovered as part of an investigation as to why BIND
	in some rare cases returns SERVFAIL for no good reason, but
	that problem I have not come to the bottom of.

>How-To-Repeat:
	Inspect the code.

	Compare to FreeBSD, and a change they did way back in 2007
	(which doesn't mention the changed error codes in the log
	entry, and also does other stuff) at

https://svnweb.freebsd.org/base/head/sys/netinet/sctp_pcb.c?r1=170090&r2=170091&;

>Fix:
--- sys/netinet/sctp_pcb.c.orig 2018-09-03 18:29:36.000000000 +0200
+++ sys/netinet/sctp_pcb.c      2018-12-11 10:17:10.000000000 +0100
@@ -1751,41 +1751,41 @@ sctp_inpcb_bind(struct socket *so, struc
                SCTP_INP_WUNLOCK(inp);
                inp_tmp = sctp_pcb_findep(addr, 0, 1);
                if (inp_tmp != NULL) {
                        /* lock guy returned and lower count
                         * note that we are not bound so inp_tmp
                         * should NEVER be inp. And it is this
                         * inp (inp_tmp) that gets the reference
                         * bump, so we must lower it.
                         */
                        SCTP_INP_WLOCK(inp_tmp);
                        SCTP_INP_DECR_REF(inp_tmp);
                        SCTP_INP_WUNLOCK(inp_tmp);
 
                        /* unlock info */
                        SCTP_INP_INFO_WUNLOCK();
-                       return (EADDRNOTAVAIL);
+                       return (EADDRINUSE);
                }
                SCTP_INP_WLOCK(inp);
                if (bindall) {
                        /* verify that no lport is not used by a singleton */
                        if (sctp_isport_inuse(inp, lport)) {
                                /* Sorry someone already has this one bound */
                                SCTP_INP_DECR_REF(inp);
                                SCTP_INP_WUNLOCK(inp);
                                SCTP_INP_INFO_WUNLOCK();
-                               return (EADDRNOTAVAIL);
+                               return (EADDRINUSE);
                        }
                }
        } else {
                /*
                 * get any port but lets make sure no one has any address
                 * with this port bound
                 */
 
                /*
                 * setup the inp to the top (I could use the union but this
                 * is just as easy
                 */
                uint32_t port_guess;
                uint16_t port_attempt;
                int not_done=1;



Home | Main Index | Thread Index | Old Index