All of lore.kernel.org
 help / color / mirror / Atom feed
* PROBLEM: raw sockets rewriting IP ID in rare cases.
@ 2010-08-13 17:07 Morgon J. Kanter
  2010-08-15  5:35 ` David Miller
  0 siblings, 1 reply; 8+ messages in thread
From: Morgon J. Kanter @ 2010-08-13 17:07 UTC (permalink / raw)
  To: netdev

[-- Attachment #1: Type: Text/Plain, Size: 2831 bytes --]

I have stumbled across what I think is a rare bug in the raw socket mechanism 
of the kernel. When attempting to send a certain packet with an IP ID of zero 
from a raw socket created with the call "socket(AF_INET, SOCK_RAW, 
IPPROTO_RAW)", the kernel will modify the IP ID field and update the checksum. 
It only seems to do it with this specific packet for some reason, similar 
packets with an IP ID of zero do not get so mangled.

To reproduce, I have attached a packet that contains the issue and code that I 
use to send it. To reproduce, compile the sending code:
$ gcc -o testpacket testpacket.c
and run it on the packet:
$ sudo ./testpacket packet1189641421

(You may need to disable your firewall or whatnot. You might also need to 
change the IP field if you don't have a route that satisfies 192.168.1.*, but 
I haven't tried to see if this works or not with another IP.) Note the packet 
itself has an IP ID field of zero. But check in Wireshark or another scanner 
scanner, and when the packet comes out the IP ID is now non-zero! I've 
attached a pcap file with the packet as it was captured from Wireshark.

To double-check that Wireshark is right, you can do the following:

$ sudo iptables -A OUTPUT -p tcp --tcp-flags SYN,ACK SYN,ACK -m u32 ! --u32 "2 
& 0xFFFF = 0" -j DROP

(for those not used to reading iptables rules, that simply blocks anything 
with a non-zero IP ID and SYN/ACK flags) When you do such, and attempt to send 
the packet using the provided program, you'll get an EPERM because Netfilter 
is blocking the packet -- even though it is supposedly going in with an IP ID 
of zero, the kernel is rewriting the ID somewhere.

This seems like a bug, because IPPROTO_RAW means IP_HDRINCL should be on and 
we should be providing the IP header exactly as we want it sent out on the 
wire. It's really puzzling because this only happens on very specific packets 
(this was taken from a modified response to the 6th probe from nmap, probes 
1-5 went fine but probe 6 was blocked).

ver_linux output:
Linux mewtwo 2.6.34-gentoo-r1 #4 SMP PREEMPT Tue Aug 10 13:35:42 EDT 2010 
x86_64 Intel(R) Core(TM)2 Duo CPU T9600 @ 2.80GHz GenuineIntel GNU/Linux
 
Gnu C                  4.3.4
Gnu make               3.81
binutils               2.20.1.20100303
util-linux             scripts/ver_linux: line 23: fdformat: command not found
mount                  support
module-init-tools      found
Linux C Library        2.11.2
Dynamic linker (ldd)   2.11.2
Procps                 3.2.8
Kbd                    1.15
Sh-utils               8.5
Modules Loaded         r8192se_pci vboxnetadp vboxnetflt vboxdrv

If you need any more information, please let me know.
Thanks,
-- Morgon

PS: My apologies if the bug format is bad or sent to the wrong place, this is 
the first time I've submitted a bug to for the kernel.

[-- Attachment #2: packet1189641421 --]
[-- Type: application/octet-stream, Size: 60 bytes --]

[-- Attachment #3: testpacket.c --]
[-- Type: text/x-csrc, Size: 829 bytes --]

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <errno.h>

int main(int argc, char **argv) {
	const char *packet_file = argv[1];
	FILE *packet_stream = fopen(packet_file, "rb");
	unsigned char packet[60];
	int sock;
	int r;
	struct sockaddr_in target;
	struct iphdr *ip;

	fread(packet, 1, 60, packet_stream);
	ip = (struct iphdr *)packet;

	if(ip->id != 0) {
		puts("IP ID is non-zero.");
		return -1;
	}

	sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
	target.sin_family = AF_INET;
	target.sin_addr.s_addr = ip->daddr;
	r = sendto(sock, packet, 60, 0, (struct sockaddr *)&target, sizeof(struct sockaddr_in));
	if(r == -1)
		if(errno == EPERM)
			puts("Errno EPERM found!");
		else
			puts("Other errno found!");
	else
		printf("No errno found! r = %d\n", r);
	
	return 0;
}

[-- Attachment #4: strange_packet.pcap --]
[-- Type: application/octet-stream, Size: 116 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: PROBLEM: raw sockets rewriting IP ID in rare cases.
  2010-08-13 17:07 PROBLEM: raw sockets rewriting IP ID in rare cases Morgon J. Kanter
@ 2010-08-15  5:35 ` David Miller
  2010-08-15 17:57   ` Morgon.J.Kanter
  0 siblings, 1 reply; 8+ messages in thread
From: David Miller @ 2010-08-15  5:35 UTC (permalink / raw)
  To: morgon.j.kanter; +Cc: netdev

From: "Morgon J. Kanter" <morgon.j.kanter@dartmouth.edu>
Date: Fri, 13 Aug 2010 13:07:38 -0400

> I have stumbled across what I think is a rare bug in the raw socket mechanism 
> of the kernel. When attempting to send a certain packet with an IP ID of zero 
> from a raw socket created with the call "socket(AF_INET, SOCK_RAW, 
> IPPROTO_RAW)", the kernel will modify the IP ID field and update the checksum. 
> It only seems to do it with this specific packet for some reason, similar 
> packets with an IP ID of zero do not get so mangled.

Even when using hdrinclude mode of RAW ipv4 sockets, if you specify
a zero ID field, the kernel will fill it in with the usual value.

It is expected behavior.

If you want the kernel to leave your ID field alone, provide a
non-zero one.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: PROBLEM: raw sockets rewriting IP ID in rare cases.
  2010-08-15  5:35 ` David Miller
@ 2010-08-15 17:57   ` Morgon.J.Kanter
  2010-08-15 20:13     ` David Miller
  0 siblings, 1 reply; 8+ messages in thread
From: Morgon.J.Kanter @ 2010-08-15 17:57 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Quoting David Miller <davem@davemloft.net>:
>> I have stumbled across what I think is a rare bug in the raw socket  
>>  mechanism
>> of the kernel. When attempting to send a certain packet with an IP   
>> ID of zero
>> from a raw socket created with the call "socket(AF_INET, SOCK_RAW,
>> IPPROTO_RAW)", the kernel will modify the IP ID field and update   
>> the checksum.
>> It only seems to do it with this specific packet for some reason, similar
>> packets with an IP ID of zero do not get so mangled.
>
> Even when using hdrinclude mode of RAW ipv4 sockets, if you specify
> a zero ID field, the kernel will fill it in with the usual value.
>
> It is expected behavior.
>
> If you want the kernel to leave your ID field alone, provide a
> non-zero one.

Is there a way to turn this behavior off, then, with raw sockets? Zero  
is the desired ID value.

Thanks,
-- Morgon

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: PROBLEM: raw sockets rewriting IP ID in rare cases.
  2010-08-15 17:57   ` Morgon.J.Kanter
@ 2010-08-15 20:13     ` David Miller
  2010-08-15 20:47       ` Eric Dumazet
  0 siblings, 1 reply; 8+ messages in thread
From: David Miller @ 2010-08-15 20:13 UTC (permalink / raw)
  To: Morgon.J.Kanter; +Cc: netdev

From: Morgon.J.Kanter@Dartmouth.edu
Date: Sun, 15 Aug 2010 13:57:41 -0400

> Is there a way to turn this behavior off, then, with raw sockets? Zero
> is the desired ID value.

No, there isn't.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: PROBLEM: raw sockets rewriting IP ID in rare cases.
  2010-08-15 20:13     ` David Miller
@ 2010-08-15 20:47       ` Eric Dumazet
  2010-08-16  0:43         ` Morgon.J.Kanter
  2010-08-16  6:26         ` Eric Dumazet
  0 siblings, 2 replies; 8+ messages in thread
From: Eric Dumazet @ 2010-08-15 20:47 UTC (permalink / raw)
  To: David Miller; +Cc: Morgon.J.Kanter, netdev

Le dimanche 15 août 2010 à 13:13 -0700, David Miller a écrit :
> From: Morgon.J.Kanter@Dartmouth.edu
> Date: Sun, 15 Aug 2010 13:57:41 -0400
> 
> > Is there a way to turn this behavior off, then, with raw sockets? Zero
> > is the desired ID value.
> 
> No, there isn't.

Just a note about IP_DF (Dont Fragment) bit.

If set, ID stay 0.

Not sure it can help Morgon.

Jiri Olsa added IP_NODEFRAG option some weeks ago (commit 7b2ff18e),
we probably could implement IP_NOIDENT option for RAW sockets ?




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: PROBLEM: raw sockets rewriting IP ID in rare cases.
  2010-08-15 20:47       ` Eric Dumazet
@ 2010-08-16  0:43         ` Morgon.J.Kanter
  2010-08-16  6:26         ` Eric Dumazet
  1 sibling, 0 replies; 8+ messages in thread
From: Morgon.J.Kanter @ 2010-08-16  0:43 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev

Quoting Eric Dumazet <eric.dumazet@gmail.com>:
> Le dimanche 15 août 2010 à 13:13 -0700, David Miller a écrit :
>> From: Morgon.J.Kanter@Dartmouth.edu
>> Date: Sun, 15 Aug 2010 13:57:41 -0400
>>
>> > Is there a way to turn this behavior off, then, with raw sockets? Zero
>> > is the desired ID value.
>>
>> No, there isn't.
>
> Just a note about IP_DF (Dont Fragment) bit.
>
> If set, ID stay 0.
>
> Not sure it can help Morgon.
>
> Jiri Olsa added IP_NODEFRAG option some weeks ago (commit 7b2ff18e),
> we probably could implement IP_NOIDENT option for RAW sockets ?

Thanks for the information. I was thinking of adding it in as a socket  
option as well, similar to that one you pointed out -- but seeing that  
makes me wonder, perhaps an "as-is" option would be more appropriate,  
instead of a different option for each field you want to leave as-is?

Thanks,
-- Morgon

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: PROBLEM: raw sockets rewriting IP ID in rare cases.
  2010-08-15 20:47       ` Eric Dumazet
  2010-08-16  0:43         ` Morgon.J.Kanter
@ 2010-08-16  6:26         ` Eric Dumazet
  2010-08-16  6:50           ` Jiri Olsa
  1 sibling, 1 reply; 8+ messages in thread
From: Eric Dumazet @ 2010-08-16  6:26 UTC (permalink / raw)
  To: David Miller, Michael Kerrisk
  Cc: Morgon.J.Kanter, netdev, Jiri Olsa, Stephen Hemminger

Le dimanche 15 août 2010 à 22:47 +0200, Eric Dumazet a écrit :

> Jiri Olsa added IP_NODEFRAG option some weeks ago (commit 7b2ff18e),
> we probably could implement IP_NOIDENT option for RAW sockets ?
> 
> 

Hmm, it seems we forgot to send to Michael some updates for
documentation.

http://www.kernel.org/doc/man-pages/online/pages/man7/ip.7.html

misses IP_FREEBIND, IP_IPSEC_POLICY, IP_XFRM_POLICY, IP_PASSSEC
IP_TRANSPARENT, IP_ORIGDSTADDR, IP_MINTTL and IP_NODEFRAG bits




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: PROBLEM: raw sockets rewriting IP ID in rare cases.
  2010-08-16  6:26         ` Eric Dumazet
@ 2010-08-16  6:50           ` Jiri Olsa
  0 siblings, 0 replies; 8+ messages in thread
From: Jiri Olsa @ 2010-08-16  6:50 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David Miller, Michael Kerrisk, Morgon.J.Kanter, netdev,
	Stephen Hemminger

On Mon, Aug 16, 2010 at 08:26:25AM +0200, Eric Dumazet wrote:
> Le dimanche 15 août 2010 à 22:47 +0200, Eric Dumazet a écrit :
> 
> > Jiri Olsa added IP_NODEFRAG option some weeks ago (commit 7b2ff18e),
> > we probably could implement IP_NOIDENT option for RAW sockets ?
> > 
> > 
> 
> Hmm, it seems we forgot to send to Michael some updates for
> documentation.
> 
> http://www.kernel.org/doc/man-pages/online/pages/man7/ip.7.html
> 
> misses IP_FREEBIND, IP_IPSEC_POLICY, IP_XFRM_POLICY, IP_PASSSEC
> IP_TRANSPARENT, IP_ORIGDSTADDR, IP_MINTTL and IP_NODEFRAG bits
> 
> 
> 

hi,
I've sent out the IP_NODEFRAG man bits together with the change
http://kerneltrap.org/mailarchive/linux-netdev/2010/6/26/6280033

jirka

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-08-16  6:50 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-13 17:07 PROBLEM: raw sockets rewriting IP ID in rare cases Morgon J. Kanter
2010-08-15  5:35 ` David Miller
2010-08-15 17:57   ` Morgon.J.Kanter
2010-08-15 20:13     ` David Miller
2010-08-15 20:47       ` Eric Dumazet
2010-08-16  0:43         ` Morgon.J.Kanter
2010-08-16  6:26         ` Eric Dumazet
2010-08-16  6:50           ` Jiri Olsa

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.