summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbluhm <bluhm@openbsd.org>2019-08-26 18:47:53 +0000
committerbluhm <bluhm@openbsd.org>2019-08-26 18:47:53 +0000
commitd3f3cb99fa834725fb68c09b10dfb3ae954359f3 (patch)
tree9d0a444840b9401cc84db2b961a91d05d0323457
parentFix file descriptor leak in config parser. Inspired by bgpd parse.y. (diff)
downloadwireguard-openbsd-d3f3cb99fa834725fb68c09b10dfb3ae954359f3.tar.xz
wireguard-openbsd-d3f3cb99fa834725fb68c09b10dfb3ae954359f3.zip
Do not use the flow of the first fragment to store ECN information.
Handle the ECN in the fragment queue. Reported-by: syzbot+0aa80b25e9041001cac8@syzkaller.appspotmail.com fix from FreeBSD; OK claudio@
-rw-r--r--sys/netinet6/frag6.c11
-rw-r--r--sys/netinet6/ip6_var.h4
2 files changed, 8 insertions, 7 deletions
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c
index aae4f0c7c9a..346411f5897 100644
--- a/sys/netinet6/frag6.c
+++ b/sys/netinet6/frag6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: frag6.c,v 1.85 2018/09/10 16:14:08 bluhm Exp $ */
+/* $OpenBSD: frag6.c,v 1.86 2019/08/26 18:47:53 bluhm Exp $ */
/* $KAME: frag6.c,v 1.40 2002/05/27 21:40:31 itojun Exp $ */
/*
@@ -224,6 +224,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto, int af)
q6->ip6q_ttl = IPV6_FRAGTTL;
q6->ip6q_src = ip6->ip6_src;
q6->ip6q_dst = ip6->ip6_dst;
+ q6->ip6q_ecn = (ntohl(ip6->ip6_flow) >> 20) & IPTOS_ECN_MASK;
q6->ip6q_unfrglen = -1; /* The 1st fragment has not arrived. */
q6->ip6q_nfrag = 0;
}
@@ -299,7 +300,6 @@ frag6_input(struct mbuf **mp, int *offp, int proto, int af)
mtx_leave(&frag6_mutex);
goto dropfrag;
}
- ip6af->ip6af_flow = ip6->ip6_flow;
ip6af->ip6af_mff = ip6f->ip6f_offlg & IP6F_MORE_FRAG;
ip6af->ip6af_off = fragoff;
ip6af->ip6af_frglen = frgpartlen;
@@ -316,9 +316,8 @@ frag6_input(struct mbuf **mp, int *offp, int proto, int af)
* if CE is set, do not lose CE.
* drop if CE and not-ECT are mixed for the same packet.
*/
- af6 = LIST_FIRST(&q6->ip6q_asfrag);
ecn = (ntohl(ip6->ip6_flow) >> 20) & IPTOS_ECN_MASK;
- ecn0 = (ntohl(af6->ip6af_flow) >> 20) & IPTOS_ECN_MASK;
+ ecn0 = q6->ip6q_ecn;
if (ecn == IPTOS_ECN_CE) {
if (ecn0 == IPTOS_ECN_NOTECT) {
mtx_leave(&frag6_mutex);
@@ -326,7 +325,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto, int af)
goto dropfrag;
}
if (ecn0 != IPTOS_ECN_CE)
- af6->ip6af_flow |= htonl(IPTOS_ECN_CE << 20);
+ q6->ip6q_ecn = IPTOS_ECN_CE;
}
if (ecn == IPTOS_ECN_NOTECT && ecn0 != IPTOS_ECN_NOTECT) {
mtx_leave(&frag6_mutex);
@@ -411,6 +410,8 @@ frag6_input(struct mbuf **mp, int *offp, int proto, int af)
ip6->ip6_plen = htons((u_short)next + offset - sizeof(struct ip6_hdr));
ip6->ip6_src = q6->ip6q_src;
ip6->ip6_dst = q6->ip6q_dst;
+ if (q6->ip6q_ecn == IPTOS_ECN_CE)
+ ip6->ip6_flow |= htonl(IPTOS_ECN_CE << 20);
nxt = q6->ip6q_nxt;
/* Delete frag6 header */
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index 30e45f4bd83..8fb28bb7be0 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_var.h,v 1.84 2018/10/10 11:46:59 reyk Exp $ */
+/* $OpenBSD: ip6_var.h,v 1.85 2019/08/26 18:47:53 bluhm Exp $ */
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
/*
@@ -76,6 +76,7 @@ struct ip6q {
int ip6q_nfrag; /* # of fragments */
u_int32_t ip6q_ident; /* fragment identification */
u_int8_t ip6q_nxt; /* ip6f_nxt in first fragment */
+ u_int8_t ip6q_ecn;
u_int8_t ip6q_ttl; /* time to live in slowtimo units */
};
@@ -85,7 +86,6 @@ struct ip6asfrag {
int ip6af_offset; /* offset in ip6af_m to next header */
int ip6af_frglen; /* fragmentable part length */
int ip6af_off; /* fragment offset */
- u_int32_t ip6af_flow; /* ip header flow id */
u_int16_t ip6af_mff; /* more fragment bit in frag off */
};