lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:	Tue, 17 Jul 2012 16:47:34 +0200
From:	András Takács <wakoond@...oond.hu>
To:	netdev@...r.kernel.org
Subject: PATCH net/ipv6/mip6.c destopt corruption


Dear All,


I have added a lot of debug messages to the kernel source and finally found the problem. When the kernel creates the skb from iovec (ip6_append_data) it sets the pointer of the network header to a wrong position. It will be shifted with 24 bytes (it is the length of the HAO dest. opt. header with paddings).

After this point, the message will be corrupted, the beginning (the first 24 bytes) of the MH part will be truncated. Later, when the kernel adds the dest. opt. header itself, there isn't any issue.

So, back to the wrong network header pointer. It is shifted by exthdrlen (= 24) by the skb_set_network_header() function. This exthdrlen comes from rt->rt6i_nfheader_len, which comes from the dst_entry chain. This nfheader_len value comes from the header_len of the desired xfrm type (in this case hao dest opt):

(net/xfrm/xfrm_policy.c: xfrm_bundle_create)
header_len += xfrm[i]->props.header_len;
if (xfrm[i]->type->flags & XFRM_TYPE_NON_FRAGMENT)
	nfheader_len += xfrm[i]->props.header_len;
...
xfrm_init_path((struct xfrm_dst *)dst0, dst, nfheader_len);

I have run a fast grep on the kernel tree, and this XFRM_TYPE_NON_FRAGMENT does not have any effect, just sets (or not) nfheader_len here. So, the following patch solves the issue:

diff -Nuar linux-3.4.2-orig/net/ipv6/mip6.c linux-3.4.2/net/ipv6/mip6.c
--- linux-3.4.2-orig/net/ipv6/mip6.c	2012-07-17 15:18:30.148777104 +0200
+++ linux-3.4.2/net/ipv6/mip6.c	2012-07-17 15:21:12.104779113 +0200
@@ -338,7 +338,7 @@
 	.description	= "MIP6DESTOPT",
 	.owner		= THIS_MODULE,
 	.proto	     	= IPPROTO_DSTOPTS,
-	.flags		= XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_LOCAL_COADDR,
+	.flags		= XFRM_TYPE_LOCAL_COADDR,
 	.init_state	= mip6_destopt_init_state,
 	.destructor	= mip6_destopt_destroy,
 	.input		= mip6_destopt_input,
@@ -471,7 +471,7 @@
 	.description	= "MIP6RT",
 	.owner		= THIS_MODULE,
 	.proto	     	= IPPROTO_ROUTING,
-	.flags		= XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_REMOTE_COADDR,
+	.flags		= XFRM_TYPE_REMOTE_COADDR,
 	.init_state	= mip6_rthdr_init_state,
 	.destructor	= mip6_rthdr_destroy,
 	.input		= mip6_rthdr_input,

What do you think about this fix? Does it have any drawback?


Ragards,
András


On Jul 16, 2012, at 3:40 PM, András Takács wrote:

> 
> Dear All,
> 
> 
> I have serious problems with HAO dest opt XFRM processing. In the past few days I have tried to find the problem, and I figured out the following:
> 
> 1. case: No XFRM rules
> It works fine (as it was described in my previous e-mail)
> 
> 2. case: HAO RO XFRM processing
> I have created the following rules manually:
> sudo ip -6 xfrm policy add src 2001:470:7210:10::11 dst 2001:470:7210:10::1000 proto 135 type 5 dir out priority 2 ptype sub tmpl src 2001:470:7210:10::11 dst 2001:470:7210:10::1000 proto hao reqid 0 mode ro
> sudo ip -6 xfrm state add src 2001:470:7210:10::11 dst 2001:470:7210:10::1000 proto hao reqid 0 mode ro replay-window 0 coa 2001:470:7210:11:20c:29ff:fe46:a0e3 sel src 2001:470:7210:10::11 dst 2001:470:7210:10::1000
> 
> The message format is corrupted, because during the xfrm processing, the beginning of the MH part will be overwritten by the DST OPT header.
> 
> 3. case: ESP TUNNEL XFRM
> I have created ESP TUNNEL XFRM rules manually, and it was worked fine. 
> So the problem has to be somewhere in the net/ipv6/mip6.c or net/ipv6/xfrm_mode_ro.c files.
> 
> -------------
> 
> I added a lot of debug printk statements to the source, and I have figured out the following:
> 
> When the kernel creates the skb from the iovec, it seems to be ok (in ip6_append_data):
> 
> skb->data to skb->tail:
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 57 39 B1 FB 87 39 B1 FB 64 92 FF FF 18 00 00 00 00 00 00 00 00 00 00 00 3B 03 05 00 00 00 00 01 00 00 00 02 01 00 03 10 20 01 04 70 72 10 00 11 02 0C 29 FF FE 46 A0 E3
> 
> Unfortunately at the beginning of the xfrm6_ro_output function, it seems to be corrupt:
> 
> 60 00 00 00 00 08 87 40 20 01 04 70 72 10 00 10 00 00 00 00 00 00 00 11 20 01 04 70 72 10 00 10 00 00 00 00 00 00 10 00 02 0C 29 FF FE 46 A0 E3
> 
> Here missing the first 24 bytes of the MH part. It is quite suspicious, because the size of the DST OPT header (with the necessary padding) is exactly same long. 
> 
> After this point xfrm6_ro_output and mip6_destopt_output works fine, and insert the DST OPT header to this truncated skb.
> 
> 
> Could you please help me to find the connection ("call - graph" ?) between ip6_append_data and xfrm6_ro_output? I can't find the point where it fails. In ip6_append_data, the beginning of the skb is reserved for the IPv6 header, but where will be this part filled with the right values?
> 
> 
> Thank you very much for your help!
> 
> 
> Regards,
> András
> 
> 
> On Jun 21, 2012, at 10:41 PM, Andras Takacs wrote:
> 
>> Dear All,
>> 
>> I'm working with Mobile IPv6 systems, and I'm setting up a new MIP6 environment. I would like to use the latest stable kernel, so I'm using 3.4.2. Unfortunately I have some serious problems with destination option XFRM processing. I have done the following tests to find the issue:
>> 
>> First case: No XFRM policies and states.
>> Sending MH messages without destopt header.
>> In this case the message format is OK, I have tested it with tcpdump and wireshark.
>> 
>> 21:33:58.817130 IP6 2001:470:7210:10::11 > 2001:470:7210:10::1000: mobility: BU seq#=1 lifetime=8
>> 	0x0000:  6000 0000 0020 8740 2001 0470 7210 0010  `......@...pr...
>> 	0x0010:  0000 0000 0000 0011 2001 0470 7210 0010  ...........pr...
>> 	0x0020:  0000 0000 0000 1000 3b03 0500 1c46 0001  ........;....F..
>> 	0x0030:  0000 0002 0100 0310 2001 0470 7210 0011  ...........pr...
>> 	0x0040:  020c 29ff fe46 a0e3                      ..)..F..
>> 
>> Second case: Adding destopt XFRM policy and state:
>> 
>> ip -6 xfrm policy add src 2001:470:7210:10::11 dst 2001:470:7210:10::1000 proto 135 type 5 dir out priority 2 ptype sub tmpl src 2001:470:7210:10::11 dst 2001:470:7210:10::1000 proto hao reqid 0 mode ro level use
>> ip -6 xfrm state add src 2001:470:7210:10::11 dst 2001:470:7210:10::1000 proto hao reqid 0 mode ro replay-window 0 coa 2001:470:7210:11:20c:29ff:fe46:a0e3 sel src 2001:470:7210:10::11 dst 2001:470:7210:10::1000
>> 
>> In this case, the message format is corrupted:
>> 
>> 21:30:42.350315 IP6 2001:470:7210:11:20c:29ff:fe46:a0e3 > 2001:470:7210:10::1000: DSTOPT mobility: type-#41 len=12
>> 	0x0000:  6000 0000 0020 3c40 2001 0470 7210 0011  `.....<@...pr...
>> 	0x0010:  020c 29ff fe46 a0e3 2001 0470 7210 0010  ..)..F.....pr...
>> 	0x0020:  0000 0000 0000 1000 8702 0102 0000 c910  ................
>> 	0x0030:  2001 0470 7210 0010 0000 0000 0000 0011  ...pr...........
>> 	0x0040:  020c 29ff fe46 a0e3 
>> 
>> As you can see, the IPv6 header is OK. Next, the destination option header is OK. Finally, the following part of the packet isn't OK. If you compare the two dump carefully, you will see, that the last 8 bytes are identical. The mip6_destopt_output function adds the destination option header correctly, but overwrites the existing MH header, and doesn't shift it after the destopt header.
>> 
>> I'm not familiar with the XFRM framework enough to fix the problem. :(
>> Maybe, could anyone help to me to fix this issue?
>> 
>> The last environment, which worked fine was built on 2.6.35 version. The problem happened between 2.6.35 and 3.4.2. Sorry, I know, it is a quite big interval. :(
>> 
>> Thanks!
>> 
>> 
>> Best regards,
>> András Takács
> 

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ