The branch main has been updated by glebius:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=9e46ff4d4cfabb4836c84d97c639c169fd0a8aaa

commit 9e46ff4d4cfabb4836c84d97c639c169fd0a8aaa
Author:     Gleb Smirnoff <[email protected]>
AuthorDate: 2023-02-03 19:33:36 +0000
Commit:     Gleb Smirnoff <[email protected]>
CommitDate: 2023-02-03 19:33:36 +0000

    netinet: don't return conflicting inpcb in in_pcbconnect_setup()
    
    Last time this inpcb was actually used was in tcp_connect()
    before c94c54e4df9a.
---
 sys/netinet/in_pcb.c     | 20 ++++----------------
 sys/netinet/in_pcb.h     |  3 +--
 sys/netinet/tcp_usrreq.c | 22 ++++++++--------------
 sys/netinet/udp_usrreq.c |  3 +--
 4 files changed, 14 insertions(+), 34 deletions(-)

diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index ab8d0acbd9a7..2a775ff5fc31 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1069,7 +1069,7 @@ in_pcbconnect(struct inpcb *inp, struct sockaddr_in *sin, 
struct ucred *cred,
        laddr = inp->inp_laddr.s_addr;
        anonport = (lport == 0);
        error = in_pcbconnect_setup(inp, sin, &laddr, &lport, &faddr, &fport,
-           NULL, cred);
+           cred);
        if (error)
                return (error);
 
@@ -1320,19 +1320,13 @@ done:
  *
  * On success, *faddrp and *fportp will be set to the remote address
  * and port. These are not updated in the error case.
- *
- * If the operation fails because the connection already exists,
- * *oinpp will be set to the PCB of that connection so that the
- * caller can decide to override it. In all other cases, *oinpp
- * is set to NULL.
  */
 int
 in_pcbconnect_setup(struct inpcb *inp, struct sockaddr_in *sin,
     in_addr_t *laddrp, u_short *lportp, in_addr_t *faddrp, u_short *fportp,
-    struct inpcb **oinpp, struct ucred *cred)
+    struct ucred *cred)
 {
        struct in_ifaddr *ia;
-       struct inpcb *oinp;
        struct in_addr laddr, faddr;
        u_short lport, fport;
        int error;
@@ -1350,8 +1344,6 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr_in 
*sin,
        INP_LOCK_ASSERT(inp);
        INP_HASH_LOCK_ASSERT(inp->inp_pcbinfo);
 
-       if (oinpp != NULL)
-               *oinpp = NULL;
        if (sin->sin_port == 0)
                return (EADDRNOTAVAIL);
        laddr.s_addr = *laddrp;
@@ -1423,13 +1415,9 @@ in_pcbconnect_setup(struct inpcb *inp, struct 
sockaddr_in *sin,
        }
 
        if (lport != 0) {
-               oinp = in_pcblookup_hash_locked(inp->inp_pcbinfo, faddr,
-                   fport, laddr, lport, 0, NULL, M_NODOM);
-               if (oinp != NULL) {
-                       if (oinpp != NULL)
-                               *oinpp = oinp;
+               if (in_pcblookup_hash_locked(inp->inp_pcbinfo, faddr,
+                   fport, laddr, lport, 0, NULL, M_NODOM) != NULL)
                        return (EADDRINUSE);
-               }
        } else {
                struct sockaddr_in lsin, fsin;
 
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index e0e630a8675e..dc248b275279 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -745,8 +745,7 @@ int in_pcbbind_setup(struct inpcb *, struct sockaddr *, 
in_addr_t *,
 int    in_pcbconnect(struct inpcb *, struct sockaddr_in *, struct ucred *,
            bool);
 int    in_pcbconnect_setup(struct inpcb *, struct sockaddr_in *, in_addr_t *,
-           u_short *, in_addr_t *, u_short *, struct inpcb **,
-           struct ucred *);
+           u_short *, in_addr_t *, u_short *, struct ucred *);
 void   in_pcbdetach(struct inpcb *);
 void   in_pcbdisconnect(struct inpcb *);
 void   in_pcbdrop(struct inpcb *);
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index b89cdd30a825..83804ac3525e 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1394,7 +1394,7 @@ struct protosw tcp6_protosw = {
 static int
 tcp_connect(struct tcpcb *tp, struct sockaddr_in *sin, struct thread *td)
 {
-       struct inpcb *inp = tptoinpcb(tp), *oinp;
+       struct inpcb *inp = tptoinpcb(tp);
        struct socket *so = tptosocket(tp);
        struct in_addr laddr;
        u_short lport;
@@ -1412,20 +1412,18 @@ tcp_connect(struct tcpcb *tp, struct sockaddr_in *sin, 
struct thread *td)
        laddr = inp->inp_laddr;
        lport = inp->inp_lport;
        error = in_pcbconnect_setup(inp, sin, &laddr.s_addr, &lport,
-           &inp->inp_faddr.s_addr, &inp->inp_fport, &oinp, td->td_ucred);
-       if (error && oinp == NULL)
-               goto out;
-       if (oinp) {
-               error = EADDRINUSE;
-               goto out;
+           &inp->inp_faddr.s_addr, &inp->inp_fport, td->td_ucred);
+       if (error) {
+               INP_HASH_WUNLOCK(&V_tcbinfo);
+               return (error);
        }
        /* Handle initial bind if it hadn't been done in advance. */
        if (inp->inp_lport == 0) {
                inp->inp_lport = lport;
                if (in_pcbinshash(inp) != 0) {
                        inp->inp_lport = 0;
-                       error = EAGAIN;
-                       goto out;
+                       INP_HASH_WUNLOCK(&V_tcbinfo);
+                       return (EAGAIN);
                }
        }
        inp->inp_laddr = laddr;
@@ -1449,11 +1447,7 @@ tcp_connect(struct tcpcb *tp, struct sockaddr_in *sin, 
struct thread *td)
                tp->ts_offset = tcp_new_ts_offset(&inp->inp_inc);
        tcp_sendseqinit(tp);
 
-       return 0;
-
-out:
-       INP_HASH_WUNLOCK(&V_tcbinfo);
-       return (error);
+       return (0);
 }
 #endif /* INET */
 
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 540045fc3bc3..f911a79519b6 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1253,8 +1253,7 @@ udp_send(struct socket *so, int flags, struct mbuf *m, 
struct sockaddr *addr,
                    sin->sin_addr.s_addr == INADDR_BROADCAST) {
                        INP_HASH_WLOCK(pcbinfo);
                        error = in_pcbconnect_setup(inp, sin, &laddr.s_addr,
-                           &lport, &faddr.s_addr, &fport, NULL,
-                           td->td_ucred);
+                           &lport, &faddr.s_addr, &fport, td->td_ucred);
                        if (error) {
                                INP_HASH_WUNLOCK(pcbinfo);
                                goto release;

Reply via email to