git: 014f98b11992 - main - udp: Fix a use-after-free in udp_multi_input()

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 16 Dec 2021 14:20:46 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=014f98b119920d70db774b6c288d1f68a70cc5e0

commit 014f98b119920d70db774b6c288d1f68a70cc5e0
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2021-12-16 14:08:47 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2021-12-16 14:17:05 +0000

    udp: Fix a use-after-free in udp_multi_input()
    
    "ip" is a pointer into the input mbuf chain, so we shouldn't access it
    after the chain is freed.
    
    Fix style at the call site while here.
    
    Reported by:    syzbot+7c8258509722af1b6145@syzkaller.appspotmail.com
    Reviewed by:    tuexen, glebius
    Fixes:          de2d47842e88 ("SMR protection for inpcbs")
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D33473
---
 sys/netinet/udp_usrreq.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index fe5327b3bd3c..554a042c612e 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -491,7 +491,6 @@ udp_multi_input(struct mbuf *m, int proto, struct sockaddr_in *udp_in)
 			break;
 		}
 	}
-	m_freem(m);
 
 	if (appends == 0) {
 		/*
@@ -505,6 +504,7 @@ udp_multi_input(struct mbuf *m, int proto, struct sockaddr_in *udp_in)
 		else
 			UDPSTAT_INC(udps_noportbcast);
 	}
+	m_freem(m);
 
 	return (IPPROTO_DONE);
 }
@@ -637,7 +637,7 @@ udp_input(struct mbuf **mp, int *offp, int proto)
 
 	if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
 	    in_broadcast(ip->ip_dst, ifp))
-			return (udp_multi_input(m, proto, udp_in));
+		return (udp_multi_input(m, proto, udp_in));
 
 	pcbinfo = udp_get_inpcbinfo(proto);