From nobody@FreeBSD.org  Wed Apr 25 15:34:04 2007
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id 909A816A407
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 25 Apr 2007 15:34:04 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [69.147.83.33])
	by mx1.freebsd.org (Postfix) with ESMTP id 769C313C459
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 25 Apr 2007 15:34:04 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id l3PFY4Ow008299
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 25 Apr 2007 15:34:04 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id l3PFT28F007776;
	Wed, 25 Apr 2007 15:29:02 GMT
	(envelope-from nobody)
Message-Id: <200704251529.l3PFT28F007776@www.freebsd.org>
Date: Wed, 25 Apr 2007 15:29:02 GMT
From: Christoph Weber-Fahr<cwf-ml@arcor.de>
To: freebsd-gnats-submit@FreeBSD.org
Subject: netstat segfaults on unusual ICMP statistics
X-Send-Pr-Version: www-3.0

>Number:         112126
>Category:       bin
>Synopsis:       [patch] netstat(1) segfaults on unusual ICMP statistics
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    maxim
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Apr 25 15:40:09 GMT 2007
>Closed-Date:    Mon May 14 18:09:23 GMT 2007
>Last-Modified:  Mon May 14 18:09:23 GMT 2007
>Originator:     Christoph Weber-Fahr
>Release:        6.1-RELEASE-p15
>Organization:
Arcor AG
>Environment:
FreeBSD xxxxx.arcor.net 6.1-RELEASE-p15 FreeBSD 6.1-RELEASE-p15 #0: Thu Apr 19 02:40:15 CEST 2007     root@xxxxx.arcor.net:/usr/obj/usr/src/sys/DL380  i386

>Description:
we have a number of very busy publicly available production servers
running FreeBSD. 

On some of these systems, netstat -s fails with a segmentation fault.
This is especially problematic, since system monitoring tools use
netstat periodically to gather statistics.

I looked into the issue in the netstats sources. The netstat utility
mainatins an internal array for ICMP type names. But for listing the
icmp statistics it relies on the ICMP_MAXTYPE kernel define pulled from
the syestem include files.

Those values are badly out of sync - ICMP_MAXTYPE is at 40, while
netstat's name array has just 19 entries. So, as soon as the kernel
has logged a stat for an icmp type > 19, netstat -s dumps core.


>How-To-Repeat:
send some ICMP packets with ICMP type > 19 to the machine
run netstat -s 
>Fix:
the appended patch

- enhances netstat's array to 40 with names from the include file
- provides a mechanism to deal gracefully with such a situation 
  schould it arise in the future again.

The patch was created and tested on FreeBSD 6.1-p15. It was also tested
on FreeBSD 6.2-p3.




Patch attached with submission follows:

--- usr.bin/netstat/inet.c.org	Wed Apr 25 15:44:51 2007
+++ usr.bin/netstat/inet.c	Wed Apr 25 17:19:17 2007
@@ -653,8 +653,32 @@
 	"information request reply",
 	"address mask request",
 	"address mask reply",
+	"#19",
+	"#20",
+	"#21",
+	"#22",
+	"#23",
+	"#24",
+	"#25",
+	"#26",
+	"#27",
+	"#28",
+	"#29",
+	"icmp traceroute",
+	"data conversion error",
+	"mobile host redirect",
+	"IPv6 where-are-you",
+	"IPv6 i-am-here",
+	"mobile registration req",
+	"mobile registration reply",
+	"#37",
+	"#38",
+	"icmp SKIP",
+	"icmp photuris",
 };
 
+static const int max_known_icmpname=40;
+
 /*
  * Dump ICMP statistics.
  */
@@ -698,8 +722,13 @@
 				printf("\tOutput histogram:\n");
 				first = 0;
 			}
-			printf("\t\t%s: %lu\n", icmpnames[i],
-				icmpstat.icps_outhist[i]);
+			if (i <= max_known_icmpname) {
+				printf("\t\t%s: %lu\n", icmpnames[i],
+					icmpstat.icps_outhist[i]);
+			} else {
+				printf("\t\tunknown ICMP #%d: %lu\n", i,
+					icmpstat.icps_outhist[i]);
+			}
 		}
 	p(icps_badcode, "\t%lu message%s with bad code fields\n");
 	p(icps_tooshort, "\t%lu message%s < minimum length\n");
@@ -713,8 +742,13 @@
 				printf("\tInput histogram:\n");
 				first = 0;
 			}
-			printf("\t\t%s: %lu\n", icmpnames[i],
-				icmpstat.icps_inhist[i]);
+			if (i <= max_known_icmpname) {
+				printf("\t\t%s: %lu\n", icmpnames[i],
+					icmpstat.icps_inhist[i]);
+			} else {
+				printf("\t\tunknown ICMP #%d: %lu\n", i,
+					icmpstat.icps_inhist[i]);
+			}
 		}
 	p(icps_reflect, "\t%lu message response%s generated\n");
 	p2(icps_badaddr, "\t%lu invalid return address%s\n");

>Release-Note:
>Audit-Trail:

From: Maxim Konovalov <maxim@macomnet.ru>
To: Christoph Weber-Fahr <cwf-ml@arcor.de>
Cc: bug-followup@freebsd.org
Subject: Re: misc/112126: netstat segfaults on unusual ICMP statistics
Date: Wed, 25 Apr 2007 22:45:35 +0400 (MSD)

 Hi Christoph,
 
 On Wed, 25 Apr 2007, 15:29-0000, Christoph Weber-Fahr wrote:
 
 > >Description:
 > we have a number of very busy publicly available production servers
 > running FreeBSD.
 >
 > On some of these systems, netstat -s fails with a segmentation
 > fault.  This is especially problematic, since system monitoring
 > tools use netstat periodically to gather statistics.
 >
 > I looked into the issue in the netstats sources. The netstat utility
 > mainatins an internal array for ICMP type names. But for listing the
 > icmp statistics it relies on the ICMP_MAXTYPE kernel define pulled
 > from the syestem include files.
 >
 > Those values are badly out of sync - ICMP_MAXTYPE is at 40, while
 > netstat's name array has just 19 entries. So, as soon as the kernel
 > has logged a stat for an icmp type > 19, netstat -s dumps core.
 >
 
 [...]
 > the appended patch
 >
 > - enhances netstat's array to 40 with names from the include file
 > - provides a mechanism to deal gracefully with such a situation
 >   schould it arise in the future again.
 >
 > The patch was created and tested on FreeBSD 6.1-p15. It was also
 > tested on FreeBSD 6.2-p3.
 >
 > Patch attached with submission follows:
 >
 > --- usr.bin/netstat/inet.c.org	Wed Apr 25 15:44:51 2007
 > +++ usr.bin/netstat/inet.c	Wed Apr 25 17:19:17 2007
 > @@ -653,8 +653,32 @@
 >  	"information request reply",
 >  	"address mask request",
 >  	"address mask reply",
 > +	"#19",
 > +	"#20",
 > +	"#21",
 > +	"#22",
 > +	"#23",
 > +	"#24",
 > +	"#25",
 > +	"#26",
 > +	"#27",
 > +	"#28",
 > +	"#29",
 > +	"icmp traceroute",
 > +	"data conversion error",
 > +	"mobile host redirect",
 > +	"IPv6 where-are-you",
 > +	"IPv6 i-am-here",
 > +	"mobile registration req",
 > +	"mobile registration reply",
 > +	"#37",
 > +	"#38",
 > +	"icmp SKIP",
 > +	"icmp photuris",
 >  };
 >
 > +static const int max_known_icmpname=40;
 > +
 >
 >  /*
 >   * Dump ICMP statistics.
 >   */
 > @@ -698,8 +722,13 @@
 >  				printf("\tOutput histogram:\n");
 >  				first = 0;
 >  			}
 > -			printf("\t\t%s: %lu\n", icmpnames[i],
 > -				icmpstat.icps_outhist[i]);
 > +			if (i <= max_known_icmpname) {
 > +				printf("\t\t%s: %lu\n", icmpnames[i],
 > +					icmpstat.icps_outhist[i]);
 > +			} else {
 > +				printf("\t\tunknown ICMP #%d: %lu\n", i,
 > +					icmpstat.icps_outhist[i]);
 > +			}
 >  		}
 >  	p(icps_badcode, "\t%lu message%s with bad code fields\n");
 >  	p(icps_tooshort, "\t%lu message%s < minimum length\n");
 > @@ -713,8 +742,13 @@
 >  				printf("\tInput histogram:\n");
 >  				first = 0;
 >  			}
 > -			printf("\t\t%s: %lu\n", icmpnames[i],
 > -				icmpstat.icps_inhist[i]);
 > +			if (i <= max_known_icmpname) {
 > +				printf("\t\t%s: %lu\n", icmpnames[i],
 > +					icmpstat.icps_inhist[i]);
 > +			} else {
 > +				printf("\t\tunknown ICMP #%d: %lu\n", i,
 > +					icmpstat.icps_inhist[i]);
 > +			}
 >  		}
 >  	p(icps_reflect, "\t%lu message response%s generated\n");
 >  	p2(icps_badaddr, "\t%lu invalid return address%s\n");
 
 It's not clear why do you need to check i <= max_known_icmpname when
 the upper loop already checked that:
 
 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++).
 
 Can I suggest an alternative patch:
 
 Index: inet.c
 ===================================================================
 RCS file: /home/ncvs/src/usr.bin/netstat/inet.c,v
 retrieving revision 1.74
 diff -u -p -r1.74 inet.c
 --- inet.c	26 Feb 2007 22:25:21 -0000	1.74
 +++ inet.c	25 Apr 2007 18:32:13 -0000
 @@ -636,7 +636,7 @@ ip_stats(u_long off __unused, const char
  #undef p1a
  }
 
 -static	const char *icmpnames[] = {
 +static	const char *icmpnames[ICMP_MAXTYPE + 1] = {
  	"echo reply",
  	"#1",
  	"#2",
 @@ -656,6 +656,28 @@ static	const char *icmpnames[] = {
  	"information request reply",
  	"address mask request",
  	"address mask reply",
 +	"#19",
 +	"#20",
 +	"#21",
 +	"#22",
 +	"#23",
 +	"#24",
 +	"#25",
 +	"#26",
 +	"#27",
 +	"#28",
 +	"#29",
 +	"icmp traceroute",
 +	"data conversion error",
 +	"mobile host redirect",
 +	"IPv6 where-are-you",
 +	"IPv6 i-am-here",
 +	"mobile registration req",
 +	"mobile registration reply",
 +	"domain name request",
 +	"domain name reply",
 +	"icmp SKIP",
 +	"icmp photuris",
  };
 
  /*
 %%%
 
 -- 
 Maxim Konovalov

From: Christoph Weber-Fahr <cwf-ml@arcor.de>
To: Maxim Konovalov <maxim@macomnet.ru>, bug-followup@freebsd.org
Cc:  
Subject: Re: misc/112126: netstat segfaults on unusual ICMP statistics
Date: Wed, 25 Apr 2007 22:37:37 +0200

 Hello,
 
 Maxim Konovalov <maxim@macomnet.ru> wrote:
 
 > It's not clear why do you need to check i <= max_known_icmpname when
 > the upper loop already checked that:
 > 
 > for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++).
 
 No!
 
 It does precise ly not do that - that upper loop is in place
 in the current (2005) version, and it eveidently did not prevent
 this problem fromn happeneing.
 
 Because that upper loop checks ICMP_MAXTYPES, which comes
 from the kernel includes, while the second check explicitly checks
 the Index size of the local const array, which is defined in the
 same file directly below it!
 
 (There might be more beautiful ways to do that in c, but as
 I'm not a c guru, none of these came in handy. You could think of
 stuff like (sizeof (icmpnames) / sizeof (icmpnames[1])), but
 I have not much of a clue about either feasibility or portability
 of these - I program C too rarely to know that without major
 reading.  Also, putting abstract knowledge about data structures
 into code isn't a programming style I like - that's a compiler's
 business, and who knows what a compiler does next year.
 
 ( and I'm not even sure that abovementioned expression works
 at all - aren't arrays in C just a convenient way to describe a
 little fancy pointer arithmetic, and the sizeof(arry) is
 actually always a pointer, too ?)
 
 > Can I suggest an alternative patch:
 
 Very funny. That's where I started - but I consider it only
 the first half of a solution. Fixing a problem isn't all,
 you should also strive to prevent its repetition.
 
 Your "fix" will break the moment someone again raises
 ICMP_MAXTYPE without changing netstat/inet.c, too.
 
 If you need a utility to rely on kernel interfaces, have
 it import them via includes.  Defining them locally, and
 crashing when the two definitions go out of sync is just
 bad coding style.
 
 Regards
 
 Christoph Weber-Fahr
 
 

From: Chris <wefa2@gmx.de>
To: bug-followup@FreeBSD.org, Maxim Konovalov <maxim@macomnet.ru>
Cc:  
Subject: Re: bin/112126: [patch] netstat(1) segfaults on unusual ICMP statistics
Date: Thu, 26 Apr 2007 00:00:36 +0200

 Hello,
 
 postcriptum - I overlooked one detail of Maxim's patch:
 
  >  +static  const char *icmpnames[ICMP_MAXTYPE + 1] = {
 
 with this he actually avoids the crash in case of an
 out of sync kernel interface (assumed the array gets
 automatically zeroed at allocation time - does it ? )
 
 But this still produces a very funny netstat output
 with just numbers and no labels. I continue to prefer
 my suggestion.
 
 Regards
 
 Christoph Weber-Fahr

From: Maxim Konovalov <maxim@macomnet.ru>
To: Christoph Weber-Fahr <cwf-ml@arcor.de>
Cc: bug-followup@freebsd.org
Subject: Re: misc/112126: netstat segfaults on unusual ICMP statistics
Date: Thu, 26 Apr 2007 08:33:27 +0400 (MSD)

 > > Can I suggest an alternative patch:
 >
 > Very funny. That's where I started - but I consider it only
 > the first half of a solution. Fixing a problem isn't all,
 > you should also strive to prevent its repetition.
 >
 > Your "fix" will break the moment someone again raises
 > ICMP_MAXTYPE without changing netstat/inet.c, too.
 
 If someone raised ICMP_MAXTYPE in netinet/ip_icmp.h the size of array
 in netstat/inet.c will be raised as well automatically because it is
 defined as
 
 static  const char *icmpnames[ICMP_MAXTYPE + 1]
 
 (Perhaps I should mention that it is required to recompile the whole
 world when such changes happen.)
 
 > If you need a utility to rely on kernel interfaces, have
 > it import them via includes.  Defining them locally, and
 > crashing when the two definitions go out of sync is just
 > bad coding style.
 
 Sure thing!  ICMP_MAXTYPE is coming from netinet/ip_icmp.h, there is
 no local definition.
 
 In your solution you have a local hardcored magic constant
 max_known_icmpname.
 
 -- 
 Maxim Konovalov

From: Maxim Konovalov <maxim@macomnet.ru>
To: Chris <wefa2@gmx.de>
Cc: bug-followup@FreeBSD.org
Subject: Re: bin/112126: [patch] netstat(1) segfaults on unusual ICMP statistics
Date: Thu, 26 Apr 2007 08:38:27 +0400 (MSD)

 On Thu, 26 Apr 2007, 00:00+0200, Chris wrote:
 
 > Hello,
 >
 > postcriptum - I overlooked one detail of Maxim's patch:
 >
 > > +static  const char *icmpnames[ICMP_MAXTYPE + 1] = {
 >
 > with this he actually avoids the crash in case of an
 > out of sync kernel interface (assumed the array gets
 > automatically zeroed at allocation time - does it ? )
 >
 > But this still produces a very funny netstat output
 > with just numbers and no labels. I continue to prefer
 > my suggestion.
 
 I see:
 
         Output histogram:
                 echo reply: 41
                 destination unreachable: 495
 [...]
         Input histogram:
                 echo reply: 12
                 destination unreachable: 1
                 echo: 41
                 #20: 7
                 icmp traceroute: 16
                 mobile registration req: 25
                 #37: 31
 
 What is yours?
 
 -- 
 Maxim Konovalov

From: Maxim Konovalov <maxim@macomnet.ru>
To: Chris <wefa2@gmx.de>
Cc: bug-followup@FreeBSD.org
Subject: Re: bin/112126: [patch] netstat(1) segfaults on unusual ICMP statistics
Date: Thu, 26 Apr 2007 09:01:10 +0400 (MSD)

 On Thu, 26 Apr 2007, 08:38+0400, Maxim Konovalov wrote:
 
 > On Thu, 26 Apr 2007, 00:00+0200, Chris wrote:
 >
 > > Hello,
 > >
 > > postcriptum - I overlooked one detail of Maxim's patch:
 > >
 > > > +static  const char *icmpnames[ICMP_MAXTYPE + 1] = {
 > >
 > > with this he actually avoids the crash in case of an
 > > out of sync kernel interface (assumed the array gets
 > > automatically zeroed at allocation time - does it ? )
 > >
 > > But this still produces a very funny netstat output
 > > with just numbers and no labels. I continue to prefer
 > > my suggestion.
 >
 > I see:
 >
 >         Output histogram:
 >                 echo reply: 41
 >                 destination unreachable: 495
 > [...]
 >         Input histogram:
 >                 echo reply: 12
 >                 destination unreachable: 1
 >                 echo: 41
 >                 #20: 7
 >                 icmp traceroute: 16
 >                 mobile registration req: 25
 >                 #37: 31
 
 You should read above as
 
         Output histogram:
                 echo reply: 41
                 destination unreachable: 511
 [...]
         Input histogram:
                 echo reply: 12
                 destination unreachable: 1
                 echo: 41
                 #20: 7
                 icmp traceroute: 16
                 mobile registration req: 25
                 domain name request: 31
 
 > What is yours?
 >
 >
 
 -- 
 Maxim Konovalov

From: Christoph Weber-Fahr <wefa2@gmx.de>
To: Maxim Konovalov <maxim@macomnet.ru>
Cc: bug-followup@FreeBSD.org
Subject: Re: bin/112126: [patch] netstat(1) segfaults on unusual ICMP statistics
Date: Fri, 27 Apr 2007 03:50:05 +0200

 Hello,
 
 Maxim Konovalov wrote:
 > On Thu, 26 Apr 2007, 00:00+0200, Chris wrote:
 >>> +static  const char *icmpnames[ICMP_MAXTYPE + 1] = {
 >> with this he actually avoids the crash in case of an
 >> out of sync kernel interface (assumed the array gets
 >> automatically zeroed at allocation time - does it ? )
 >>
 >> But this still produces a very funny netstat output
 >> with just numbers and no labels. I continue to prefer
 >> my suggestion.
 > 
 > I see:
 > 
 >         Output histogram:
 >                 echo reply: 41
 >                 destination unreachable: 495
 > [...]
 >         Input histogram:
 >                 echo reply: 12
 >                 destination unreachable: 1
 >                 echo: 41
 >                 #20: 7
 >                 icmp traceroute: 16
 >                 mobile registration req: 25
 >                 #37: 31
 
 Actually, you don't see that. You'd see:
 
           Input histogram:
                   echo reply: 12
                   destination unreachable: 1
                   echo: 41
                   #20: 7
                   icmp traceroute: 16
                   mobile registration req: 25
                   #37: 31
 		 8
                   15
 
 Note the last two untagged values. They
 are created when the kernel, which in
 the meantime has a ICM_MAXTYPE at, say, 49,
 has logged 8 packets of type 44, and 15 of type 47.
 
 > What is yours?
 
 My variant would produce:
 
           Input histogram:
                   echo reply: 12
                   destination unreachable: 1
                   echo: 41
                   #20: 7
                   icmp traceroute: 16
                   mobile registration req: 25
                   #37: 31
 		 unknown ICMP #44: 8
                   unknown ICMP #47: 15
 
 This is preferable because it both gives more
 information (you still get the type number) and
 doesn't break the tag: value format that many
 monitoring setups use for simple parsing.
 
 Regards
 
 Christoph Weber-Fahr
 

From: Maxim Konovalov <maxim@macomnet.ru>
To: Christoph Weber-Fahr <wefa2@gmx.de>
Cc: bug-followup@FreeBSD.org
Subject: Re: bin/112126: [patch] netstat(1) segfaults on unusual ICMP statistics
Date: Fri, 27 Apr 2007 09:12:24 +0400 (MSD)

 On Fri, 27 Apr 2007, 03:50+0200, Christoph Weber-Fahr wrote:
 
 > Hello,
 >
 > Maxim Konovalov wrote:
 > > On Thu, 26 Apr 2007, 00:00+0200, Chris wrote:
 > > > > +static  const char *icmpnames[ICMP_MAXTYPE + 1] = {
 > > > with this he actually avoids the crash in case of an
 > > > out of sync kernel interface (assumed the array gets
 > > > automatically zeroed at allocation time - does it ? )
 > > >
 > > > But this still produces a very funny netstat output
 > > > with just numbers and no labels. I continue to prefer
 > > > my suggestion.
 > >
 > > I see:
 > >
 > >         Output histogram:
 > >                 echo reply: 41
 > >                 destination unreachable: 495
 > > [...]
 > >         Input histogram:
 > >                 echo reply: 12
 > >                 destination unreachable: 1
 > >                 echo: 41
 > >                 #20: 7
 > >                 icmp traceroute: 16
 > >                 mobile registration req: 25
 > >                 #37: 31
 >
 > Actually, you don't see that. You'd see:
 
 I just run hacked version of ping(8):
 
 for i in `jot 255`; do; /usr/obj/usr/src/sbin/ping/ping -c 1 -x $i;
 
 Here what I see after it:
 
         Input histogram:
                 echo reply: 4969
                 #1: 1
                 #2: 1
                 destination unreachable: 4
                 source quench: 1
                 routing redirect: 1
                 #6: 1
                 #7: 1
                 echo: 27
                 router advertisement: 1
                 router solicitation: 1
                 time exceeded: 1
                 parameter problem: 1
                 time stamp: 1
                 time stamp reply: 2
                 information request: 1
                 information request reply: 1
                 address mask request: 1
                 address mask reply: 2
                 #19: 1
                 #20: 1
                 #21: 1
                 #22: 1
                 #23: 1
                 #24: 1
                 #25: 1
                 #26: 1
                 #27: 1
                 #28: 1
                 #29: 1
                 icmp traceroute: 1
                 datagram conversion error: 1
                 mobile host redirect: 1
                 IPv6 where-are-you: 1
                 IPv6 i-am-here: 1
                 mobile registration req: 1
                 mobile registration reply: 1
                 domain name request: 1
                 domain name reply: 1
                 icmp SKIP: 1
                 icmp photuris: 1
 
 >          Input histogram:
 >                  echo reply: 12
 >                  destination unreachable: 1
 >                  echo: 41
 >                  #20: 7
 >                  icmp traceroute: 16
 >                  mobile registration req: 25
 >                  #37: 31
 > 		 8
 >                  15
 >
 > Note the last two untagged values. They
 > are created when the kernel, which in
 > the meantime has a ICM_MAXTYPE at, say, 49,
 > has logged 8 packets of type 44, and 15 of type 47.
 >
 > > What is yours?
 >
 > My variant would produce:
 >
 >          Input histogram:
 >                  echo reply: 12
 >                  destination unreachable: 1
 >                  echo: 41
 >                  #20: 7
 >                  icmp traceroute: 16
 >                  mobile registration req: 25
 >                  #37: 31
 > 		 unknown ICMP #44: 8
 >                  unknown ICMP #47: 15
 >
 > This is preferable because it both gives more
 > information (you still get the type number) and
 > doesn't break the tag: value format that many
 > monitoring setups use for simple parsing.
 
 icmpstat.icps_outhist and icps_inhist are definde this way:
 
 	u_long icps_outhist[ICMP_MAXTYPE + 1];
 	u_long icps_inhist[ICMP_MAXTYPE + 1];
 
 How do you fit types > ICMP_MAXTYPE + 1 there?
 
 -- 
 Maxim Konovalov

From: Christoph Weber-Fahr <cwf-ml@arcor.de>
To: Maxim Konovalov <maxim@macomnet.ru>, bug-followup@freebsd.org
Cc:  
Subject: Re: misc/112126: netstat segfaults on unusual ICMP statistics
Date: Fri, 27 Apr 2007 16:35:35 +0200

 Hello,
 
 Maxim Konovalov <maxim@macomnet.ru> wrote:
 > On Fri, 27 Apr 2007, 03:50+0200, Christoph Weber-Fahr wrote:
 >> Input histogram:
 >> echo reply: 12
 >> destination unreachable: 1
 >> echo: 41
 >> #20: 7
 >> icmp traceroute: 16
 >> mobile registration req: 25
 >> #37: 31
 >> 8
 >> 15
 >>
 >> Note the last two untagged values. They
 >> are created when the kernel, which in
 >> the meantime has a ICM_MAXTYPE at, say, 49,
 >> has logged 8 packets of type 44, and 15 of type 47.
 
 > icmpstat.icps_outhist and icps_inhist are definde this way:
 > 
 > u_long icps_outhist[ICMP_MAXTYPE + 1];
 > u_long icps_inhist[ICMP_MAXTYPE + 1];
 > 
 > How do you fit types > ICMP_MAXTYPE + 1 there?
 
 Not at all. We are debating the case when ICMP_MAXTYPE
 in the kernel gets raised without adapting netstat.
 
 To test this you would not only have had modified ping, but also
 recompiled a kernel with a modified ICMP_MAXTYPE.
 
 My scenario above assumed ICMP_MAXTYPE to be 49.
 
 Regards
 
 Christoph Weber-Fahr

From: Maxim Konovalov <maxim@macomnet.ru>
To: Christoph Weber-Fahr <cwf-ml@arcor.de>
Cc: bug-followup@freebsd.org
Subject: Re: misc/112126: netstat segfaults on unusual ICMP statistics
Date: Fri, 27 Apr 2007 21:37:17 +0400 (MSD)

 On Fri, 27 Apr 2007, 16:35+0200, Christoph Weber-Fahr wrote:
 
 > Hello,
 >
 > Maxim Konovalov <maxim@macomnet.ru> wrote:
 > > On Fri, 27 Apr 2007, 03:50+0200, Christoph Weber-Fahr wrote:
 > > > Input histogram:
 > > > echo reply: 12
 > > > destination unreachable: 1
 > > > echo: 41
 > > > #20: 7
 > > > icmp traceroute: 16
 > > > mobile registration req: 25
 > > > #37: 31
 > > > 8
 > > > 15
 > > >
 > > > Note the last two untagged values. They
 > > > are created when the kernel, which in
 > > > the meantime has a ICM_MAXTYPE at, say, 49,
 > > > has logged 8 packets of type 44, and 15 of type 47.
 >
 > > icmpstat.icps_outhist and icps_inhist are definde this way:
 > >
 > > u_long icps_outhist[ICMP_MAXTYPE + 1];
 > > u_long icps_inhist[ICMP_MAXTYPE + 1];
 > >
 > > How do you fit types > ICMP_MAXTYPE + 1 there?
 >
 > Not at all. We are debating the case when ICMP_MAXTYPE
 > in the kernel gets raised without adapting netstat.
 >
 > To test this you would not only have had modified ping, but also
 > recompiled a kernel with a modified ICMP_MAXTYPE.
 >
 > My scenario above assumed ICMP_MAXTYPE to be 49.
 
 OK, what about this version:
 
 Index: inet.c
 ===================================================================
 RCS file: /home/ncvs/src/usr.bin/netstat/inet.c,v
 retrieving revision 1.74
 diff -u -p -r1.74 inet.c
 --- inet.c	26 Feb 2007 22:25:21 -0000	1.74
 +++ inet.c	27 Apr 2007 17:32:01 -0000
 @@ -636,26 +636,48 @@ ip_stats(u_long off __unused, const char
  #undef p1a
  }
 
 -static	const char *icmpnames[] = {
 -	"echo reply",
 +static	const char *icmpnames[ICMP_MAXTYPE + 1] = {
 +	"echo reply",			/* RFC 792 */
  	"#1",
  	"#2",
 -	"destination unreachable",
 -	"source quench",
 -	"routing redirect",
 +	"destination unreachable",	/* RFC 792 */
 +	"source quench",		/* RFC 792 */
 +	"routing redirect",		/* RFC 792 */
  	"#6",
  	"#7",
 -	"echo",
 -	"router advertisement",
 -	"router solicitation",
 -	"time exceeded",
 -	"parameter problem",
 -	"time stamp",
 -	"time stamp reply",
 -	"information request",
 -	"information request reply",
 -	"address mask request",
 -	"address mask reply",
 +	"echo",				/* RFC 792 */
 +	"router advertisement",		/* RFC 1256 */
 +	"router solicitation",		/* RFC 1256 */
 +	"time exceeded",		/* RFC 792 */
 +	"parameter problem",		/* RFC 792 */
 +	"time stamp",			/* RFC 792 */
 +	"time stamp reply",		/* RFC 792 */
 +	"information request",		/* RFC 792 */
 +	"information request reply",	/* RFC 792 */
 +	"address mask request",		/* RFC 950 */
 +	"address mask reply",		/* RFC 950 */
 +	"#19",
 +	"#20",
 +	"#21",
 +	"#22",
 +	"#23",
 +	"#24",
 +	"#25",
 +	"#26",
 +	"#27",
 +	"#28",
 +	"#29",
 +	"icmp traceroute",		/* RFC 1393 */
 +	"datagram conversion error",	/* RFC 1475 */
 +	"mobile host redirect",
 +	"IPv6 where-are-you",
 +	"IPv6 i-am-here",
 +	"mobile registration req",
 +	"mobile registration reply",
 +	"domain name request",		/* RFC 1788 */
 +	"domain name reply",		/* RFC 1788 */
 +	"icmp SKIP",
 +	"icmp photuris",		/* RFC 2521 */
  };
 
  /*
 @@ -701,8 +723,12 @@ icmp_stats(u_long off __unused, const ch
  				printf("\tOutput histogram:\n");
  				first = 0;
  			}
 -			printf("\t\t%s: %lu\n", icmpnames[i],
 -				icmpstat.icps_outhist[i]);
 +			if (icmpnames[i] != NULL)
 +				printf("\t\t%s: %lu\n", icmpnames[i],
 +					icmpstat.icps_outhist[i]);
 +			else
 +				printf("\t\tunknown ICMP #%d: %lu\n", i,
 +					icmpstat.icps_outhist[i]);
  		}
  	p(icps_badcode, "\t%lu message%s with bad code fields\n");
  	p(icps_tooshort, "\t%lu message%s < minimum length\n");
 @@ -716,8 +742,12 @@ icmp_stats(u_long off __unused, const ch
  				printf("\tInput histogram:\n");
  				first = 0;
  			}
 -			printf("\t\t%s: %lu\n", icmpnames[i],
 -				icmpstat.icps_inhist[i]);
 +			if (icmpnames[i] != NULL)
 +				printf("\t\t%s: %lu\n", icmpnames[i],
 +			 		icmpstat.icps_inhist[i]);
 +			else
 +				printf("\t\tunknown ICMP #%d: %lu\n", i,
 +					icmpstat.icps_inhist[i]);
  		}
  	p(icps_reflect, "\t%lu message response%s generated\n");
  	p2(icps_badaddr, "\t%lu invalid return address%s\n");
 %%%
 
 I see:
 
                 #28: 1
                 #29: 1
                 icmp traceroute: 1
                 mobile registration req: 1
                 mobile registration reply: 1
                 domain name request: 1
                 domain name reply: 1
                 icmp SKIP: 1
                 icmp photuris: 1
                 unknown ICMP #41: 1
                 unknown ICMP #42: 1
                 unknown ICMP #43: 1
 
 -- 
 Maxim Konovalov

From: Christoph Weber-Fahr <cwf-ml@arcor.de>
To: bug-followup@FreeBSD.org, Maxim Konovalov <maxim@macomnet.ru>
Cc:  
Subject: Re: bin/112126: [patch] netstat segfaults on unusual ICMP statistics>
Date: Mon, 30 Apr 2007 13:06:48 +0200

 Hello,
 
 Maxim Konovalov <maxim@macomnet.ru>
  > OK, what about this version:
 
 Looks good and gets the job done.
 
 If you prefer your version, you won't hear
 any complains from me :-)
 
 Regards
 
 Christoph Weber-Fahr
 
 
 
State-Changed-From-To: open->patched 
State-Changed-By: maxim 
State-Changed-When: Mon Apr 30 12:12:54 UTC 2007 
State-Changed-Why:  
FIxed in HEAD.  Thanks! 


Responsible-Changed-From-To: freebsd-bugs->maxim 
Responsible-Changed-By: maxim 
Responsible-Changed-When: Mon Apr 30 12:12:54 UTC 2007 
Responsible-Changed-Why:  
MFC reminder. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=112126 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/112126: commit references a PR
Date: Mon, 30 Apr 2007 12:27:10 +0000 (UTC)

 maxim       2007-04-30 12:27:04 UTC
 
   FreeBSD src repository
 
   Modified files:
     usr.bin/netstat      inet.c 
   Log:
   o Fill the list of icmp types; make its size depend on ICMP_MAXTYPE.
   o Print "unknown ICMP" instead of "(null)" if we don't have a description         for a icmp type.
   
   Based on code
   
   Submitted by:   Christoph Weber-Fahr
   PR:             misc/112126
   MFC after:      2 weeks
   
   Revision  Changes    Path
   1.75      +50 -20    src/usr.bin/netstat/inet.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: maxim 
State-Changed-When: Mon May 14 18:09:05 UTC 2007 
State-Changed-Why:  
Merged to RELENG_6. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=112126 
>Unformatted:
