diff options
author | 2019-08-26 18:47:53 +0000 | |
---|---|---|
committer | 2019-08-26 18:47:53 +0000 | |
commit | d3f3cb99fa834725fb68c09b10dfb3ae954359f3 (patch) | |
tree | 9d0a444840b9401cc84db2b961a91d05d0323457 | |
parent | Fix file descriptor leak in config parser. Inspired by bgpd parse.y. (diff) | |
download | wireguard-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.c | 11 | ||||
-rw-r--r-- | sys/netinet6/ip6_var.h | 4 |
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 */ }; |