From nobody@FreeBSD.org  Thu Aug 19 16:16:16 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id F06B7106566C
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 19 Aug 2010 16:16:16 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id DFB308FC0A
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 19 Aug 2010 16:16:16 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o7JGGG42021750
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 19 Aug 2010 16:16:16 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o7JGGGtF021749;
	Thu, 19 Aug 2010 16:16:16 GMT
	(envelope-from nobody)
Message-Id: <201008191616.o7JGGGtF021749@www.freebsd.org>
Date: Thu, 19 Aug 2010 16:16:16 GMT
From: Dmitrij Tejblum <tejblum@yandex-team.ru>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch] [ipfw] panic due to bpf write to ipfw interface
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         149807
>Category:       kern
>Synopsis:       [patch] [ipfw] panic due to bpf write to ipfw interface
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    maxim
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Aug 19 16:20:01 UTC 2010
>Closed-Date:    Wed Oct 20 12:39:18 UTC 2010
>Last-Modified:  Wed Oct 20 12:39:18 UTC 2010
>Originator:     Dmitrij Tejblum
>Release:        8.1-STABLE
>Organization:
OOO Yandex
>Environment:
>Description:
ipfw create a pseudo-interface named ipfw0. It looks pretty much like an ethernet interface. If a program attach a bpf to the interface and send a multicast packet via it, a panic will occur.

(Of course, sending packets to the ipfw0 interface is not useful. But some programs may do it. E.g., an CDP or LLDP daemon by default would try to send its packets to all interfaces in the systems, including ipfw0, if it's configured.)

The cause of the panic is unitialized `if_broadcastaddr' field of the ipfw0's ifnet struct. The field is supposed to be initialized, and it is used in e.g. sys/net/bpf.c
>How-To-Repeat:
On a system with ipfw configured, install net-mgmt/openlldp port, run lldpd, and wait for a minute or so.
>Fix:


Patch attached with submission follows:

--- sys/netinet/ipfw/ip_fw_log.c	2010-03-23 12:58:59.000000000 +0300
+++ sys/netinet/ipfw/ip_fw_log.c	2010-08-19 19:33:39.000000000 +0400
@@ -103,6 +103,9 @@ log_dummy(struct ifnet *ifp, u_long cmd,
 	return EINVAL;
 }
 
+static const u_char ipfwbroadcastaddr[6] =
+                        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+                        
 void
 ipfw_log_bpf(int onoff)
 {
@@ -124,6 +127,7 @@ ipfw_log_bpf(int onoff)
 		ifp->if_addrlen = 6;
 		ifp->if_hdrlen = 14;
 		if_attach(ifp);
+		ifp->if_broadcastaddr = ipfwbroadcastaddr;
 		ifp->if_baudrate = IF_Mbps(10);
 		bpfattach(ifp, DLT_EN10MB, 14);
 		log_if = ifp;


>Release-Note:
>Audit-Trail:

From: Maxim Konovalov <maxim.konovalov@gmail.com>
To: Dmitrij Tejblum <tejblum@yandex-team.ru>
Cc: bug-followup@freebsd.org
Subject: Re: kern/149807: [patch] [ipfw] panic due to bpf write to ipfw
 interface
Date: Thu, 19 Aug 2010 20:39:42 +0400 (MSD)

 > ipfw create a pseudo-interface named ipfw0. It looks pretty much
 > like an ethernet interface. If a program attach a bpf to the
 > interface and send a multicast packet via it, a panic will occur.
 >
 > (Of course, sending packets to the ipfw0 interface is not useful.
 > But some programs may do it. E.g., an CDP or LLDP daemon by default
 > would try to send its packets to all interfaces in the systems,
 > including ipfw0, if it's configured.)
 >
 This remembers me kern/149097.  Sounds similar?
 
 -- 
 Maxim Konovalov
Responsible-Changed-From-To: freebsd-bugs->maxim 
Responsible-Changed-By: maxim 
Responsible-Changed-When: Thu Aug 19 16:42:50 UTC 2010 
Responsible-Changed-Why:  
I read this code recently, over to me. 

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

From: Dmitrij Tejblum <tejblum@yandex-team.ru>
To: Maxim Konovalov <maxim.konovalov@gmail.com>
Cc: bug-followup@freebsd.org
Subject: Re: kern/149807: [patch] [ipfw] panic due to bpf write to ipfw interface
Date: Thu, 19 Aug 2010 20:42:10 +0400

 Maxim Konovalov wrote:
 >> ipfw create a pseudo-interface named ipfw0. It looks pretty much
 >> like an ethernet interface. If a program attach a bpf to the
 >> interface and send a multicast packet via it, a panic will occur.
 >>
 >> (Of course, sending packets to the ipfw0 interface is not useful.
 >> But some programs may do it. E.g., an CDP or LLDP daemon by default
 >> would try to send its packets to all interfaces in the systems,
 >> including ipfw0, if it's configured.)
 >>
 >>      
 > This remembers me kern/149097.  Sounds similar?
 >    
 Indeed, it is the same issue.
 
 
 -- 
 Dima
 

From: Dmitrij Tejblum <tejblum@yandex-team.ru>
To: Maxim Konovalov <maxim.konovalov@gmail.com>
Cc: bug-followup@freebsd.org
Subject: Re: kern/149807: [patch] [ipfw] panic due to bpf write to ipfw
 interface
Date: Fri, 20 Aug 2010 13:49:10 +0400 (MSD)

 Obviously I was a bit too quick sending the previous patch. It removed the 
 panic, but opened an mbuf leak. A more correct version would be like 
 this:
 
 
 --- sys/netinet/ipfw/ip_fw_log.c.00	2010-03-23 12:58:59.000000000 +0300
 +++ sys/netinet/ipfw/ip_fw_log.c	2010-08-20 13:10:51.000000000 +0400
 @@ -103,6 +103,24 @@
   	return EINVAL;
   }
 
 +static int
 +ipfw_log_output(struct ifnet *ifp, struct mbuf *m,
 +	struct sockaddr *dst, struct route *ro)
 +{
 +	if (m != NULL)
 +		m_freem(m);
 +	return EINVAL;
 +}
 +
 +static int
 +ipfw_log_start(struct ifnet* ifp)
 +{
 +	panic("ipfw_log_start() must not be called");
 +}
 +
 +static const u_char ipfwbroadcastaddr[6] =
 +                        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 +
   void
   ipfw_log_bpf(int onoff)
   {
 @@ -119,11 +137,12 @@
   		ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST;
   		ifp->if_init = (void *)log_dummy;
   		ifp->if_ioctl = log_dummy;
 -		ifp->if_start = (void *)log_dummy;
 -		ifp->if_output = (void *)log_dummy;
 +		ifp->if_start = ipfw_log_start;
 +		ifp->if_output = ipfw_log_output;
   		ifp->if_addrlen = 6;
   		ifp->if_hdrlen = 14;
   		if_attach(ifp);
 +		ifp->if_broadcastaddr = ipfwbroadcastaddr;
   		ifp->if_baudrate = IF_Mbps(10);
   		bpfattach(ifp, DLT_EN10MB, 14);
   		log_if = ifp;
 

From: Maxim Konovalov <maxim.konovalov@gmail.com>
To: Dmitrij Tejblum <tejblum@yandex-team.ru>
Cc: bug-followup@freebsd.org, Vsevolod Volkov <vvv@lucky.net>
Subject: Re: kern/149807: [patch] [ipfw] panic due to bpf write to ipfw
 interface
Date: Mon, 23 Aug 2010 17:39:24 +0400 (MSD)

 Corrected patch (ipfw_log_start() had wrong return type) for
 consideration.
 
 Index: sys/netinet/ipfw/ip_fw_log.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/netinet/ipfw/ip_fw_log.c,v
 retrieving revision 1.11
 diff -u -r1.11 ip_fw_log.c
 --- sys/netinet/ipfw/ip_fw_log.c	9 Jul 2010 11:27:33 -0000	1.11
 +++ sys/netinet/ipfw/ip_fw_log.c	23 Aug 2010 09:13:38 -0000
 @@ -103,6 +103,24 @@
  	return EINVAL;
  }
 
 +static int
 +ipfw_log_output(struct ifnet *ifp, struct mbuf *m,
 +	struct sockaddr *dst, struct route *ro)
 +{
 +	if (m != NULL)
 +		m_freem(m);
 +	return EINVAL;
 +}
 +
 +static void
 +ipfw_log_start(struct ifnet* ifp)
 +{
 +	panic("ipfw_log_start() must not be called");
 +}
 +
 +static const u_char ipfwbroadcastaddr[6] =
 +	{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 +
  void
  ipfw_log_bpf(int onoff)
  {
 @@ -119,11 +137,12 @@
  		ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST;
  		ifp->if_init = (void *)log_dummy;
  		ifp->if_ioctl = log_dummy;
 -		ifp->if_start = (void *)log_dummy;
 -		ifp->if_output = (void *)log_dummy;
 +		ifp->if_start = ipfw_log_start;
 +		ifp->if_output = ipfw_log_output;
  		ifp->if_addrlen = 6;
  		ifp->if_hdrlen = 14;
  		if_attach(ifp);
 +		ifp->if_broadcastaddr = ipfwbroadcastaddr;
  		ifp->if_baudrate = IF_Mbps(10);
  		bpfattach(ifp, DLT_EN10MB, 14);
  		log_if = ifp;
 %%%
 
 -- 
 Maxim Konovalov
State-Changed-From-To: open->patched 
State-Changed-By: maxim 
State-Changed-When: Mon Aug 30 09:30:24 UTC 2010 
State-Changed-Why:  
Committed to HEAD.  Thanks! 

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

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/149807: commit references a PR
Date: Mon, 30 Aug 2010 09:30:06 +0000 (UTC)

 Author: maxim
 Date: Mon Aug 30 09:29:51 2010
 New Revision: 211992
 URL: http://svn.freebsd.org/changeset/base/211992
 
 Log:
   o Some programs could send broadcast/multicast traffic to ipfw
   pseudo-interface.  This leads to a panic due to uninitialized
   if_broadcastaddr address.  Initialize it and implement ip_output()
   method to prevent mbuf leak later.
   
   ipfw pseudo-interface should never send anything therefore call
   panic(9) in if_start() method.
   
   PR:		kern/149807
   Submitted by:	Dmitrij Tejblum
   MFC after:	2 weeks
 
 Modified:
   head/sys/netinet/ipfw/ip_fw_log.c
 
 Modified: head/sys/netinet/ipfw/ip_fw_log.c
 ==============================================================================
 --- head/sys/netinet/ipfw/ip_fw_log.c	Mon Aug 30 08:23:22 2010	(r211991)
 +++ head/sys/netinet/ipfw/ip_fw_log.c	Mon Aug 30 09:29:51 2010	(r211992)
 @@ -103,6 +103,24 @@ log_dummy(struct ifnet *ifp, u_long cmd,
  	return EINVAL;
  }
  
 +static int
 +ipfw_log_output(struct ifnet *ifp, struct mbuf *m,
 +	struct sockaddr *dst, struct route *ro)
 +{
 +	if (m != NULL)
 +		m_freem(m);
 +	return EINVAL;
 +}
 +
 +static void
 +ipfw_log_start(struct ifnet* ifp)
 +{
 +	panic("ipfw_log_start() must not be called");
 +}
 +
 +static const u_char ipfwbroadcastaddr[6] =
 +	{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 +
  void
  ipfw_log_bpf(int onoff)
  {
 @@ -119,11 +137,12 @@ ipfw_log_bpf(int onoff)
  		ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST;
  		ifp->if_init = (void *)log_dummy;
  		ifp->if_ioctl = log_dummy;
 -		ifp->if_start = (void *)log_dummy;
 -		ifp->if_output = (void *)log_dummy;
 +		ifp->if_start = ipfw_log_start;
 +		ifp->if_output = ipfw_log_output;
  		ifp->if_addrlen = 6;
  		ifp->if_hdrlen = 14;
  		if_attach(ifp);
 +		ifp->if_broadcastaddr = ipfwbroadcastaddr;
  		ifp->if_baudrate = IF_Mbps(10);
  		bpfattach(ifp, DLT_EN10MB, 14);
  		log_if = ifp;
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: maxim 
State-Changed-When: Wed Oct 20 12:38:50 UTC 2010 
State-Changed-Why:  
Merged to RELENG_8. 

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