aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv6/netfilter/ip6_tables.c11
-rw-r--r--net/ipv6/netfilter/ip6t_ah.c7
-rw-r--r--net/ipv6/netfilter/ip6t_frag.c7
-rw-r--r--net/ipv6/netfilter/ip6t_hbh.c7
-rw-r--r--net/ipv6/netfilter/ip6t_rt.c7
5 files changed, 31 insertions, 8 deletions
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index f0328c7bc1c9..53bf977cca63 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1440,6 +1440,9 @@ static void __exit ip6_tables_fini(void)
1440 * If target header is found, its offset is set in *offset and return protocol 1440 * If target header is found, its offset is set in *offset and return protocol
1441 * number. Otherwise, return -1. 1441 * number. Otherwise, return -1.
1442 * 1442 *
1443 * If the first fragment doesn't contain the final protocol header or
1444 * NEXTHDR_NONE it is considered invalid.
1445 *
1443 * Note that non-1st fragment is special case that "the protocol number 1446 * Note that non-1st fragment is special case that "the protocol number
1444 * of last header" is "next header" field in Fragment header. In this case, 1447 * of last header" is "next header" field in Fragment header. In this case,
1445 * *offset is meaningless and fragment offset is stored in *fragoff if fragoff 1448 * *offset is meaningless and fragment offset is stored in *fragoff if fragoff
@@ -1463,12 +1466,12 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
1463 if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { 1466 if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) {
1464 if (target < 0) 1467 if (target < 0)
1465 break; 1468 break;
1466 return -1; 1469 return -ENOENT;
1467 } 1470 }
1468 1471
1469 hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); 1472 hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
1470 if (hp == NULL) 1473 if (hp == NULL)
1471 return -1; 1474 return -EBADMSG;
1472 if (nexthdr == NEXTHDR_FRAGMENT) { 1475 if (nexthdr == NEXTHDR_FRAGMENT) {
1473 unsigned short _frag_off, *fp; 1476 unsigned short _frag_off, *fp;
1474 fp = skb_header_pointer(skb, 1477 fp = skb_header_pointer(skb,
@@ -1477,7 +1480,7 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
1477 sizeof(_frag_off), 1480 sizeof(_frag_off),
1478 &_frag_off); 1481 &_frag_off);
1479 if (fp == NULL) 1482 if (fp == NULL)
1480 return -1; 1483 return -EBADMSG;
1481 1484
1482 _frag_off = ntohs(*fp) & ~0x7; 1485 _frag_off = ntohs(*fp) & ~0x7;
1483 if (_frag_off) { 1486 if (_frag_off) {
@@ -1488,7 +1491,7 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
1488 *fragoff = _frag_off; 1491 *fragoff = _frag_off;
1489 return hp->nexthdr; 1492 return hp->nexthdr;
1490 } 1493 }
1491 return -1; 1494 return -ENOENT;
1492 } 1495 }
1493 hdrlen = 8; 1496 hdrlen = 8;
1494 } else if (nexthdr == NEXTHDR_AUTH) 1497 } else if (nexthdr == NEXTHDR_AUTH)
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index ec1b1608156c..46486645eb75 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -54,9 +54,14 @@ match(const struct sk_buff *skb,
54 const struct ip6t_ah *ahinfo = matchinfo; 54 const struct ip6t_ah *ahinfo = matchinfo;
55 unsigned int ptr; 55 unsigned int ptr;
56 unsigned int hdrlen = 0; 56 unsigned int hdrlen = 0;
57 int err;
57 58
58 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL) < 0) 59 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL);
60 if (err < 0) {
61 if (err != -ENOENT)
62 *hotdrop = 1;
59 return 0; 63 return 0;
64 }
60 65
61 ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); 66 ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
62 if (ah == NULL) { 67 if (ah == NULL) {
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
index 78d9c8b9e28a..cd22eaaccdca 100644
--- a/net/ipv6/netfilter/ip6t_frag.c
+++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -52,9 +52,14 @@ match(const struct sk_buff *skb,
52 struct frag_hdr _frag, *fh; 52 struct frag_hdr _frag, *fh;
53 const struct ip6t_frag *fraginfo = matchinfo; 53 const struct ip6t_frag *fraginfo = matchinfo;
54 unsigned int ptr; 54 unsigned int ptr;
55 int err;
55 56
56 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0) 57 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL);
58 if (err < 0) {
59 if (err != -ENOENT)
60 *hotdrop = 1;
57 return 0; 61 return 0;
62 }
58 63
59 fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); 64 fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
60 if (fh == NULL) { 65 if (fh == NULL) {
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
index d32a205e3af2..3f25babe0440 100644
--- a/net/ipv6/netfilter/ip6t_hbh.c
+++ b/net/ipv6/netfilter/ip6t_hbh.c
@@ -65,9 +65,14 @@ match(const struct sk_buff *skb,
65 u8 _opttype, *tp = NULL; 65 u8 _opttype, *tp = NULL;
66 u8 _optlen, *lp = NULL; 66 u8 _optlen, *lp = NULL;
67 unsigned int optlen; 67 unsigned int optlen;
68 int err;
68 69
69 if (ipv6_find_hdr(skb, &ptr, match->data, NULL) < 0) 70 err = ipv6_find_hdr(skb, &ptr, match->data, NULL);
71 if (err < 0) {
72 if (err != -ENOENT)
73 *hotdrop = 1;
70 return 0; 74 return 0;
75 }
71 76
72 oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); 77 oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
73 if (oh == NULL) { 78 if (oh == NULL) {
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index bcb2e168a5bc..54d7d14134fd 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -58,9 +58,14 @@ match(const struct sk_buff *skb,
58 unsigned int hdrlen = 0; 58 unsigned int hdrlen = 0;
59 unsigned int ret = 0; 59 unsigned int ret = 0;
60 struct in6_addr *ap, _addr; 60 struct in6_addr *ap, _addr;
61 int err;
61 62
62 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0) 63 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL);
64 if (err < 0) {
65 if (err != -ENOENT)
66 *hotdrop = 1;
63 return 0; 67 return 0;
68 }
64 69
65 rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); 70 rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
66 if (rh == NULL) { 71 if (rh == NULL) {