Page MenuHomeFreeBSD

D16851.id47122.diff
No OneTemporary

D16851.id47122.diff

Index: sys/netinet6/frag6.c
===================================================================
--- sys/netinet6/frag6.c
+++ sys/netinet6/frag6.c
@@ -66,6 +66,11 @@
#include <netinet/in_systm.h> /* for ECN definitions */
#include <netinet/ip.h> /* for ECN definitions */
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/sctp.h>
+#include <netinet/udp.h>
+
#include <security/mac/mac_framework.h>
/*
@@ -83,6 +88,8 @@
static void frag6_remque(struct ip6q *, uint32_t bucket);
static void frag6_freef(struct ip6q *, uint32_t bucket);
+static int ip6_validhdrchain(uint8_t, uint16_t);
+
struct ip6qbucket {
struct ip6q ip6q;
struct mtx lock;
@@ -328,6 +335,20 @@
)
break;
+ /*
+ * If first fragment (frag offset is 0) doesn't have carry an upper
+ * layer header drop it per RFC7112
+ */
+ fragoff = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK);
+ if (fragoff == 0 &&
+ !ip6_validhdrchain(ip6f->ip6f_nxt, frgpartlen)) {
+
+ /* remove any fragments that have arrived in this chain */
+ if (q6 != head)
+ frag6_freef(q6, hash);
+ goto dropfrag;
+ }
+
if (q6 == head) {
/*
* the first fragment to arrive, create a reassembly queue.
@@ -382,7 +403,6 @@
* If it's the 1st fragment, record the length of the
* unfragmentable part and the next header of the fragment header.
*/
- fragoff = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK);
if (fragoff == 0) {
q6->ip6q_unfrglen = offset - sizeof(struct ip6_hdr) -
sizeof(struct ip6_frag);
@@ -959,3 +979,43 @@
m->m_flags |= M_FRAGMENTED;
return (0);
}
+
+/*
+ * Ensure that proto is an upper layer header and there is enough space for the
+ * upper layer header.
+ */
+static int
+ip6_validhdrchain(uint8_t proto, uint16_t length)
+{
+ switch (proto) {
+ case IPPROTO_ICMPV6:
+ if (length < sizeof(struct icmp6_hdr))
+ return 0;
+ return 1;
+ case IPPROTO_IPV6:
+ if (length < sizeof(struct ip6_hdr))
+ return 0;
+ return 1;
+ case IPPROTO_ESP:
+ if (length < sizeof(uint32_t))
+ return 0;
+ return 1;
+ case IPPROTO_SCTP:
+ if (length < sizeof(struct sctphdr))
+ return 0;
+ return 1;
+ case IPPROTO_TCP:
+ if (length < TCP_MAXHLEN)
+ return 0;
+ return 1;
+ case IPPROTO_UDP:
+ case IPPROTO_UDPLITE:
+ if (length < sizeof(struct udphdr))
+ return 0;
+ return 1;
+ default:
+ /* not a known upper layer protocol */
+ return 0;
+ }
+ return 0;
+}

File Metadata

Mime Type
text/plain
Expires
Tue, Jun 16, 1:03 PM (11 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33987983
Default Alt Text
D16851.id47122.diff (2 KB)

Event Timeline