The branch stable/13 has been updated by ae:

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

commit 9f46322cad4797932c70da1b9aa96a93cc8491ba
Author:     Andrey V. Elsukov <a...@freebsd.org>
AuthorDate: 2021-02-11 08:55:39 +0000
Commit:     Andrey V. Elsukov <a...@freebsd.org>
CommitDate: 2021-02-15 10:48:10 +0000

    [udp] fix possible mbuf and lock leak in udp_input().
    
    In error case we can leave `inp' locked, also we need to free
    mbuf chain `m' in the same case. Release the lock and use `badunlocked'
    label to exit with freed mbuf. Also modify UDP error statistic to
    match the IPv6 code.
    
    Remove redundant INP_RUNLOCK() from the `if (last == NULL)' block,
    there are no ways to reach this point with locked `inp'.
    
    Obtained from:  Yandex LLC
    Sponsored by:   Yandex LLC
    
    (cherry picked from commit c6ded47d0bae801589b564dbe01dccd474edaed0)
---
 sys/netinet/udp_usrreq.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 52304ddd6584..c2ad9381850e 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -610,9 +610,11 @@ udp_input(struct mbuf **mp, int *offp, int proto)
                                                    uh);
                                        if (udp_append(last, ip, n, iphlen,
                                                udp_in)) {
-                                               goto inp_lost;
+                                               INP_RUNLOCK(inp);
+                                               goto badunlocked;
                                        }
                                }
+                               /* Release PCB lock taken on previous pass. */
                                INP_RUNLOCK(last);
                        }
                        last = inp;
@@ -635,9 +637,11 @@ udp_input(struct mbuf **mp, int *offp, int proto)
                         * to send an ICMP Port Unreachable for a broadcast
                         * or multicast datgram.)
                         */
-                       UDPSTAT_INC(udps_noportbcast);
-                       if (inp)
-                               INP_RUNLOCK(inp);
+                       UDPSTAT_INC(udps_noport);
+                       if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)))
+                               UDPSTAT_INC(udps_noportmcast);
+                       else
+                               UDPSTAT_INC(udps_noportbcast);
                        goto badunlocked;
                }
                if (proto == IPPROTO_UDPLITE)
@@ -646,7 +650,6 @@ udp_input(struct mbuf **mp, int *offp, int proto)
                        UDP_PROBE(receive, NULL, last, ip, last, uh);
                if (udp_append(last, ip, m, iphlen, udp_in) == 0)
                        INP_RUNLOCK(last);
-       inp_lost:
                return (IPPROTO_DONE);
        }
 
_______________________________________________
dev-commits-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"

Reply via email to