From yar@comp.chem.msu.su  Tue Nov 28 10:16:59 2006
Return-Path: <yar@comp.chem.msu.su>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id B882816A505
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 28 Nov 2006 10:16:59 +0000 (UTC)
	(envelope-from yar@comp.chem.msu.su)
Received: from jujik.ramtel.ru (jujik.ramtel.ru [81.19.64.112])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 31D3843E3E
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 28 Nov 2006 10:14:08 +0000 (GMT)
	(envelope-from yar@comp.chem.msu.su)
Received: from jujik.ramtel.ru (localhost [127.0.0.1])
	by jujik.ramtel.ru (8.13.8/8.13.8) with ESMTP id kASADo6v086216
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 28 Nov 2006 13:13:50 +0300 (MSK)
	(envelope-from yar@comp.chem.msu.su)
Received: (from yar@localhost)
	by jujik.ramtel.ru (8.13.8/8.13.8/Submit) id kASADosH086215;
	Tue, 28 Nov 2006 13:13:50 +0300 (MSK)
	(envelope-from yar@comp.chem.msu.su)
Message-Id: <200611281013.kASADosH086215@jujik.ramtel.ru>
Date: Tue, 28 Nov 2006 13:13:50 +0300 (MSK)
From: Yar Tikhiy <yar@comp.chem.msu.su>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: Network stack may modify read-only mbuf chain copies
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         105943
>Category:       kern
>Synopsis:       Network stack may modify read-only mbuf chain copies
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-net
>State:          suspended
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Nov 28 10:20:09 GMT 2006
>Closed-Date:    
>Last-Modified:  Sun Apr 29 09:15:27 GMT 2007
>Originator:     Yar Tikhiy
>Release:        FreeBSD 7.0-CURRENT i386
>Organization:
none
>Environment:
	
	At least, all versions found in the CVS repository.

>Description:
	
	The m_copym() function and its historic alias m_copy() are
	used all over the kernel to get a copy of a mbuf chain.
	However, at least some code fails to account for the fact
	that the copy is read-only due to the mbuf clusters from
	the original chain not actually copied, but merely referenced
	by the new chain.

	The most obvious case is the routines calling if_simloop()
	to return a copy of a network packet up the stack.  It is
	done to let the stack see its own broadcast traffic if the
	outgoing interface is simplex.  Such routines all use
	m_copym() to make the copy, but the upper layers of the
	stack are not prohibited from modifying the mbuf chain they
	get on input.  Consequently, the original chain ready to
	be transmitted to the network may be damaged unpredictably.
	The damage can have various consequences, from broken packets
	sent to system crashes.

	In addition, there might be more places in the kernel where
	m_copym() or m_copy() is used although a writable copy is
	needed.

>How-To-Repeat:
	
	Although the problem didn't manifested itself for ages, a
	recent change in the distribution of data over a mbuf chain
	has finally triggered it in CURRENT.  A stock generator of
	broadcast traffic is rwhod(8).  As soon as its packet is
	longer than ~256 bytes and so it doesn't fit in one simple
	mbuf, it appears damaged on the network.  To reach the
	threshold length, just open multiple terminal sessions to
	the system.

16:15:28.212810 IP truncated-ip - 6865 bytes missing! (tos 0x0, ttl  64, id 28554, offset 0, \
                flags [none], proto: UDP (17), length: 7169, bad cksum 11c (->c64b)!) \
                10.10.10.4.513 > 10.10.10.255.513: UDP, length 276
        0x0000:  4500 1c01 6f8a 0000 4011 011c 0a0a 0a04  E...o...@.......
                      ^^^^                ^^^^ broken fields
         0x0010:  0a0a 0aff 0201 0201 011c 0000 0101 0000  ................
         0x0020:  4565 9ef0 0000 0000 6467 0000 0000 0000  Ee......dg......
         0x0030:  0000 0000 0000 0000 0000 0000 0000 0000  ................
         0x0040:  0000 0000 0000 0000 0000 001a 0000 000e  ................
         0x0050:  0000 0005 4564 a5e7 7474 7976 3000 0000  ....Ed..ttyv0...
         0x0060:  726f 6f74 0000 0000 4565 9d4a 0000 01a6  root....Ee.J....
         0x0070:  7474 7976 3100 0000 726f 6f74 0000 0000  ttyv1...root....
         0x0080:  4565 9d4d 0000 000c 7474 7976 3200 0000  Ee.M....ttyv2...
         0x0090:  726f 6f74 0000 0000 4565 9d4f 0000 0099  root....Ee.O....
         0x00a0:  7474 7976 3300 0000 726f 6f74 0000 0000  ttyv3...root....
         0x00b0:  4565 9d52 0000 019e 7474 7976 3400 0000  Ee.R....ttyv4...
         0x00c0:  726f 6f74 0000 0000 4565 9d54 0000 019c  root....Ee.T....
         0x00d0:  7474 7976 3500 0000 726f 6f74 0000 0000  ttyv5...root....
         0x00e0:  4565 9d59 0000 0198 7474 7976 3600 0000  Ee.Y....ttyv6...
         0x00f0:  726f 6f74 0000 0000 4565 9d5b 0000 0195  root....Ee.[....
         0x0100:  7474 7976 3700 0000 726f 6f74 0000 0000  ttyv7...root....
         0x0110:  4565 9d5e 0000 0000 7474 7970 3100 0000  Ee.^....ttyp1...
         0x0120:  7961 7200 0000 0000 4565 8361 0000 04b2  yar.....Ee.a....

>Fix:

	The initial idea is to drop all the bogus and often buggy
	code around if_simloop() calls and add a flag to if_simloop()
	indicating that the mbuf chain must be fully duplicated
	with m_dup() and then the copy is to be processed.  In
	STABLE, the flag can be indicated by adding M_COPYALL to
	the hlen argument.  M_COPYALL is a very large value that
	allows for the trick.  So ABI will be preserved in STABLE.

	At the same time, the other cases of m_copym() usage should
	be revised thoroughly.
>Release-Note:
>Audit-Trail:

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/105943: commit references a PR
Date: Sun, 24 Dec 2006 08:52:29 +0000 (UTC)

 yar         2006-12-24 08:52:13 UTC
 
   FreeBSD src repository
 
   Modified files:
     sys/net              if_ethersubr.c 
   Log:
   Note that rev. 1.221 introduced a local workaround for a general problem.
   Add a pointer to the relevant PR for future reference.  The whole comment
   will be OK to remove as soon as the general solution is applied.
   
   PR:     kern/105943
   
   Revision  Changes    Path
   1.222     +4 -0      src/sys/net/if_ethersubr.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"
 

From: Yar Tikhiy <yar@comp.chem.msu.su>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/105943: Network stack may modify read-only mbuf chain copies
Date: Sun, 24 Dec 2006 12:14:09 +0300

 JFTR:
 
 A local workaround was independently applied to if_ethersubr.c in
 its rev. 1.221.  However, less used L2 modules such as arcnet, fddi,
 and token ring still suffer from the same bug.  Moreover, as already
 noted in this PR, other callers of m_copym() may get it wrong, too.
 
 Unfortunately, I neither suffer from this issue personally nor have
 free time to fully investigate and address it out of general interest.
 OTOH, financial support can motivate me to do so.  Granting the
 number of source files potentially involved (~45) and the amount
 of thorough testing requred, it would be not less than 10 hours
 worth of work.
 
 -- 
 Yar
State-Changed-From-To: open->suspended 
State-Changed-By: linimon 
State-Changed-When: Sun Apr 29 09:13:29 UTC 2007 
State-Changed-Why:  
A workaround has been committed, but a general solution has not yet been 
committed.  Awaiting an interested person. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=105943 
Responsible-Changed-From-To: freebsd-bugs->freebsd-net 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sun Apr 29 09:15:10 UTC 2007 
Responsible-Changed-Why:  
This should probably be assigned to -net. 

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