if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
                return -EACCES;
 
+       /* See if the address matches any of the addresses we may have
+        * already bound before checking against other endpoints.
+        */
+       if (sctp_bind_addr_match(bp, addr, sp))
+               return -EINVAL;
+
        /* Make sure we are allowed to bind here.
         * The function sctp_get_port_local() does duplicate address
         * detection.
         */
        addr->v4.sin_port = htons(snum);
        if ((ret = sctp_get_port_local(sk, addr))) {
-               if (ret == (long) sk) {
-                       /* This endpoint has a conflicting address. */
-                       return -EINVAL;
-               } else {
-                       return -EADDRINUSE;
-               }
+               return -EADDRINUSE;
        }
 
        /* Refresh ephemeral port.  */
                        struct sctp_endpoint *ep2;
                        ep2 = sctp_sk(sk2)->ep;
 
-                       if (reuse && sk2->sk_reuse &&
-                           sk2->sk_state != SCTP_SS_LISTENING)
+                       if (sk == sk2 ||
+                           (reuse && sk2->sk_reuse &&
+                            sk2->sk_state != SCTP_SS_LISTENING))
                                continue;
 
                        if (sctp_bind_addr_conflict(&ep2->base.bind_addr, addr,
        if (!ep->base.bind_addr.port) {
                if (sctp_autobind(sk))
                        return -EAGAIN;
-       } else
+       } else {
+               if (sctp_get_port(sk, inet_sk(sk)->num)) {
+                       sk->sk_state = SCTP_SS_CLOSED;
+                       return -EADDRINUSE;
+               }
                sctp_sk(sk)->bind_hash->fastreuse = 0;
+       }
 
        sctp_hash_endpoint(ep);
        return 0;