kern/87306: IP_PORTRANGE_HIGH causes bad UDP checksum
Maxim Konovalov
maxim at macomnet.ru
Wed Oct 12 01:50:18 PDT 2005
The following reply was made to PR kern/87306; it has been noted by GNATS.
From: Maxim Konovalov <maxim at macomnet.ru>
To: bms at freebsd.org
Cc: Rickard Lind <rickard.lind at ntier.se>, bug-followup at freebsd.org
Subject: Re: kern/87306: IP_PORTRANGE_HIGH causes bad UDP checksum
Date: Wed, 12 Oct 2005 12:41:06 +0400 (MSD)
> >Description:
> Due to a mixup of two fields, setting the socket option
> IP_PORTRANGE_HIGH on a UDP socket in order to bind a high (random)
> port affects the checksum calculation such that the resulting
> checksum is incorrect.
> >How-To-Repeat:
> Create a UDP (SOCK_DGRAM) socket. Set the IP_PORTRANGE_HIGH socket
> option. Bind with a zero port. Send some data to another host.
> Ethereal on the receiveing host reports the UDP checksum as
> incorrect.
> >Fix:
> The problem is that the flag INP_ONESBCAST has the same value (0x10)
> as the flag INP_HIGHPORT in sys/netinet/in_pcb.h, and INP_ONESBCAST
> is tested against the inp_flags field (in sys/netinet/udp_usrreq.c
> and sys/netinet/raw_ip.c) when it SHOULD be tested against the
> inp_vflag field. This causes the checksum calculation on line 867 in
> udp_usrreq.c to use the broadcast address leading to an incorrect
> checksum.
Ricard, it seems you analysis is correct. Thanks for the high quality
bug report!
Bruce, what is your opinion?
Index: raw_ip.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/raw_ip.c,v
retrieving revision 1.154
diff -u -r1.154 raw_ip.c
--- raw_ip.c 4 Oct 2005 18:19:21 -0000 1.154
+++ raw_ip.c 12 Oct 2005 08:32:15 -0000
@@ -316,7 +316,7 @@
ipstat.ips_rawout++;
}
- if (inp->inp_flags & INP_ONESBCAST)
+ if (inp->inp_vflags & INP_ONESBCAST)
flags |= IP_SENDONES;
#ifdef MAC
Index: udp_usrreq.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.177
diff -u -r1.177 udp_usrreq.c
--- udp_usrreq.c 26 Sep 2005 20:25:16 -0000 1.177
+++ udp_usrreq.c 12 Oct 2005 08:32:31 -0000
@@ -860,14 +860,14 @@
ipflags |= IP_ROUTETOIF;
if (inp->inp_socket->so_options & SO_BROADCAST)
ipflags |= IP_ALLOWBROADCAST;
- if (inp->inp_flags & INP_ONESBCAST)
+ if (inp->inp_vflags & INP_ONESBCAST)
ipflags |= IP_SENDONES;
/*
* Set up checksum and output datagram.
*/
if (udpcksum) {
- if (inp->inp_flags & INP_ONESBCAST)
+ if (inp->inp_vflags & INP_ONESBCAST)
faddr.s_addr = INADDR_BROADCAST;
ui->ui_sum = in_pseudo(ui->ui_src.s_addr, faddr.s_addr,
htons((u_short)len + sizeof(struct udphdr) + IPPROTO_UDP));
%%%
--
Maxim Konovalov
More information about the freebsd-bugs
mailing list