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>