diff options
| -rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 11 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_ah.c | 7 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_frag.c | 7 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_hbh.c | 7 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_rt.c | 7 |
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) { |
