Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 Dec 2016 20:54:38 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r310034 - projects/ipsec/sys/netipsec
Message-ID:  <201612132054.uBDKscTw023801@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Tue Dec 13 20:54:38 2016
New Revision: 310034
URL: https://svnweb.freebsd.org/changeset/base/310034

Log:
  Fix possible bug in udp_ipsec_output().
  
  m_makespace() returns mbuf where UDP header is stored. And it is possible,
  that it is not the same mbuf where IP header is. So, don't touch original
  mbuf, just return error code.

Modified:
  projects/ipsec/sys/netipsec/ipsec.h
  projects/ipsec/sys/netipsec/ipsec_output.c
  projects/ipsec/sys/netipsec/udpencap.c

Modified: projects/ipsec/sys/netipsec/ipsec.h
==============================================================================
--- projects/ipsec/sys/netipsec/ipsec.h	Tue Dec 13 20:35:57 2016	(r310033)
+++ projects/ipsec/sys/netipsec/ipsec.h	Tue Dec 13 20:54:38 2016	(r310034)
@@ -325,7 +325,7 @@ int tcp_ipsec_output(struct mbuf *, stru
 int udp_ipsec_pcbctl(struct inpcb *, struct sockopt *);
 int udp_ipsec_input(struct mbuf *, int, int);
 void udp_ipsec_adjust_cksum(struct mbuf *, struct secasvar *, int, int);
-int udp_ipsec_output(struct mbuf **, struct secasvar *);
+int udp_ipsec_output(struct mbuf *, struct secasvar *);
 
 int ipsec_chkreplay(uint32_t, struct secasvar *);
 int ipsec_updatereplay(uint32_t, struct secasvar *);

Modified: projects/ipsec/sys/netipsec/ipsec_output.c
==============================================================================
--- projects/ipsec/sys/netipsec/ipsec_output.c	Tue Dec 13 20:35:57 2016	(r310033)
+++ projects/ipsec/sys/netipsec/ipsec_output.c	Tue Dec 13 20:54:38 2016	(r310034)
@@ -599,7 +599,7 @@ ipsec_process_done(struct mbuf *m, struc
 	 * Do UDP encapsulation if SA requires it.
 	 */
 	if (sav->natt != NULL) {
-		error = udp_ipsec_output(&m, sav);
+		error = udp_ipsec_output(m, sav);
 		if (error != 0)
 			goto bad;
 	}

Modified: projects/ipsec/sys/netipsec/udpencap.c
==============================================================================
--- projects/ipsec/sys/netipsec/udpencap.c	Tue Dec 13 20:35:57 2016	(r310033)
+++ projects/ipsec/sys/netipsec/udpencap.c	Tue Dec 13 20:54:38 2016	(r310034)
@@ -211,10 +211,10 @@ udp_ipsec_input(struct mbuf *m, int off,
 }
 
 int
-udp_ipsec_output(struct mbuf **mp, struct secasvar *sav)
+udp_ipsec_output(struct mbuf *m, struct secasvar *sav)
 {
 	struct udphdr *udp;
-	struct mbuf *m;
+	struct mbuf *n;
 	struct ip *ip;
 	int hlen, off;
 
@@ -223,16 +223,19 @@ udp_ipsec_output(struct mbuf **mp, struc
 	if (sav->sah->saidx.dst.sa.sa_family == AF_INET6)
 		return (EAFNOSUPPORT);
 
-	ip = mtod(*mp, struct ip *);
+	ip = mtod(m, struct ip *);
 	hlen = ip->ip_hl << 2;
-	m = m_makespace(*mp, hlen, sizeof(*udp), &off);
-	if (m == NULL) {
+	n = m_makespace(m, hlen, sizeof(*udp), &off);
+	if (n == NULL) {
 		DPRINTF(("%s: m_makespace for udphdr failed\n", __func__));
 		return (ENOBUFS);
 	}
-	*mp = m;
-	ip = mtod(m, struct ip *);
-	udp = mtodo(m, off);
+	/*
+	 * IP header should stay in the same place of mbuf m.
+	 * m_makespace() can add new mbuf or move the remaining data into
+	 * the end of mbuf space. Thus mtod() isn't required for ip pointer.
+	 */
+	udp = mtodo(n, off);
 	udp->uh_dport = sav->natt->dport;
 	udp->uh_sport = sav->natt->sport;
 	udp->uh_sum = 0;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201612132054.uBDKscTw023801>