* [PATCH 2.4 13/18]: Backport fixes for ip6t_hbh
@ 2004-12-20 7:15 Patrick McHardy
0 siblings, 0 replies; only message in thread
From: Patrick McHardy @ 2004-12-20 7:15 UTC (permalink / raw)
To: David S. Miller; +Cc: netfilter-devel
[-- Attachment #1: Type: text/plain, Size: 30 bytes --]
Backport fixes for ip6t_hbh.
[-- Attachment #2: 13.diff --]
[-- Type: text/x-patch, Size: 5261 bytes --]
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
# 2004/12/05 23:29:45+01:00 yasuyuki.kozakai@toshiba.co.jp
# [NETFILTER]: Backport fixes for ip6t_hbh
#
# This patch fixes the following bugs in ip6t_hbh.c:
#
# - The cast of the pointer to the next IPv6 extension header is wrong.
# - hdrlen may underflow.
# - (u16)*optdesc causes to alignment problem.
# - The calculation of the offset to next option is wrong. In the case
# that the type isn't 0, it should be "Opt Data Len" field + 2
# (see RFC2460).
#
# Signed-off-by: Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp>
# Signed-off-by: Patrick McHardy <kaber@trash.net>
#
# net/ipv6/netfilter/ip6t_hbh.c
# 2004/12/05 23:29:44+01:00 yasuyuki.kozakai@toshiba.co.jp +38 -36
# [NETFILTER]: Backport fixes for ip6t_hbh
#
# This patch fixes the following bugs in ip6t_hbh.c:
#
# - The cast of the pointer to the next IPv6 extension header is wrong.
# - hdrlen may underflow.
# - (u16)*optdesc causes to alignment problem.
# - The calculation of the offset to next option is wrong. In the case
# that the type isn't 0, it should be "Opt Data Len" field + 2
# (see RFC2460).
#
# Signed-off-by: Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp>
# Signed-off-by: Patrick McHardy <kaber@trash.net>
#
diff -Nru a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
--- a/net/ipv6/netfilter/ip6t_hbh.c 2004-12-20 07:01:26 +01:00
+++ b/net/ipv6/netfilter/ip6t_hbh.c 2004-12-20 07:01:26 +01:00
@@ -11,8 +11,6 @@
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter_ipv6/ip6t_opts.h>
-#define LOW(n) (n & 0x00FF)
-
#define HOPBYHOP 1
EXPORT_NO_SYMBOLS;
@@ -40,8 +38,8 @@
* 0 -> invariant
* 1 -> can change the routing
* (Type & 0x1F) Type
- * 0 -> PAD0 (only 1 byte!)
- * 1 -> PAD1 LENGTH info (total length = length + 2)
+ * 0 -> Pad1 (only 1 byte!)
+ * 1 -> PadN LENGTH info (total length = length + 2)
* C0 | 2 -> JUMBO 4 x x x x ( xxxx > 64k )
* 5 -> RTALERT 2 x x
*/
@@ -64,7 +62,8 @@
unsigned int ptr;
unsigned int hdrlen = 0;
unsigned int ret = 0;
- u_int16_t *optdesc = NULL;
+ u8 *opttype = NULL;
+ unsigned int optlen;
/* type of the 1st exthdr */
nexthdr = skb->nh.ipv6h->nexthdr;
@@ -91,7 +90,7 @@
break;
}
- hdr=(void *)(skb->data)+ptr;
+ hdr = (void *)(skb->data + ptr);
/* Calculate the header length */
if (nexthdr == NEXTHDR_FRAGMENT) {
@@ -153,7 +152,7 @@
return 0;
}
- optsh=(void *)(skb->data)+ptr;
+ optsh = (void *)(skb->data + ptr);
DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, optsh->hdrlen);
@@ -169,7 +168,6 @@
((optinfo->hdrlen == hdrlen) ^
!!(optinfo->invflags & IP6T_OPTS_INV_LEN)));
- temp = len = 0;
ptr += 2;
hdrlen -= 2;
if ( !(optinfo->flags & IP6T_OPTS_OPTS) ){
@@ -180,48 +178,52 @@
DEBUGP("Strict ");
DEBUGP("#%d ",optinfo->optsnr);
for(temp=0; temp<optinfo->optsnr; temp++){
- optdesc = (void *)(skb->data)+ptr;
+ /* type field exists ? */
+ if (ptr > skb->len - 1 || hdrlen < 1)
+ break;
+ opttype = (void *)(skb->data + ptr);
+
/* Type check */
- if ( (unsigned char)*optdesc !=
- (optinfo->opts[temp] & 0xFF00)>>8 ){
+ if (*opttype != (optinfo->opts[temp] & 0xFF00)>>8){
DEBUGP("Tbad %02X %02X\n",
- (unsigned char)*optdesc,
- (optinfo->opts[temp] &
- 0xFF00)>>8);
+ *opttype,
+ (optinfo->opts[temp] & 0xFF00)>>8);
return 0;
} else {
DEBUGP("Tok ");
}
/* Length check */
- if (((optinfo->opts[temp] & 0x00FF) != 0xFF) &&
- (unsigned char)*optdesc != 0){
- if ( ntohs((u16)*optdesc) !=
- optinfo->opts[temp] ){
- DEBUGP("Lbad %02X %04X %04X\n",
- (unsigned char)*optdesc,
- ntohs((u16)*optdesc),
- optinfo->opts[temp]);
+ if (*opttype) {
+ u16 spec_len;
+
+ /* length field exists ? */
+ if (ptr > skb->len - 2 || hdrlen < 2)
+ break;
+ optlen = *((u8 *)(skb->data + ptr + 1));
+ spec_len = optinfo->opts[temp] & 0x00FF;
+
+ if (spec_len != 0x00FF && spec_len != optlen) {
+ DEBUGP("Lbad %02X %04X\n", optlen,
+ spec_len);
return 0;
- } else {
- DEBUGP("Lok ");
}
- }
- /* Step to the next */
- if ((unsigned char)*optdesc == 0){
- DEBUGP("PAD0 \n");
- ptr++;
- hdrlen--;
+ DEBUGP("Lok ");
+ optlen += 2;
} else {
- ptr += LOW(ntohs(*optdesc));
- hdrlen -= LOW(ntohs(*optdesc));
- DEBUGP("len%04X \n",
- LOW(ntohs(*optdesc)));
+ DEBUGP("Pad1\n");
+ optlen = 1;
}
- if (ptr > skb->len || ( !hdrlen &&
- (temp != optinfo->optsnr - 1))) {
+
+ /* Step to the next */
+ DEBUGP("len%04X \n", optlen);
+
+ if ((ptr > skb->len - optlen || hdrlen < optlen) &&
+ (temp < optinfo->optsnr - 1)) {
DEBUGP("new pointer is too large! \n");
break;
}
+ ptr += optlen;
+ hdrlen -= optlen;
}
if (temp == optinfo->optsnr)
return ret;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2004-12-20 7:15 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-12-20 7:15 [PATCH 2.4 13/18]: Backport fixes for ip6t_hbh Patrick McHardy
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.