From nobody@FreeBSD.org  Fri Mar 17 10:00:36 2006
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id A418F16A425
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 17 Mar 2006 10:00:36 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 7266143D45
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 17 Mar 2006 10:00:36 +0000 (GMT)
	(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 k2HA0Tr0018832
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 17 Mar 2006 10:00:29 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id k2HA0Tm4018831;
	Fri, 17 Mar 2006 10:00:29 GMT
	(envelope-from nobody)
Message-Id: <200603171000.k2HA0Tm4018831@www.freebsd.org>
Date: Fri, 17 Mar 2006 10:00:29 GMT
From: Zhouyi Zhou <zhouyi04@ios.cn>
To: freebsd-gnats-submit@FreeBSD.org
Subject: MAC (Mandatory Access Control) and IPSEC can not coexist
X-Send-Pr-Version: www-2.3

>Number:         94599
>Category:       kern
>Synopsis:       [mac] MAC (Mandatory Access Control) and IPSEC can not coexist
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    rwatson
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Mar 17 10:10:13 GMT 2006
>Closed-Date:    Mon Apr 03 09:03:33 GMT 2006
>Last-Modified:  Mon Apr 03 09:03:33 GMT 2006
>Originator:     Zhouyi Zhou
>Release:        FreeBSD 6.0 and FreeBSD 5.4 both
>Organization:
Institute of Software, Chinese Academy of Sciences
>Environment:
FreeBSD zzy.ios 6.0-RELEASE FreeBSD 6.0-RELEASE #13: Fri Mar 17 17:11:04 UTC 2006     root@zzy.ios:/root/Earth/earth/sys/i386/compile/earth  i386

>Description:
Once you set up your machine with both MAC/MLS and IPSEC support. Then your
connect from a TCP client from one machine to a TCP server on another machine,
the TCP server will crack. 


The reason is somethings has modified the mags that used to store the MAC
information.
>How-To-Repeat:
Once you set up your machine with both MAC/MLS and IPSEC support. Then your
connect from a TCP client from one machine to a TCP server on another machine,
the TCP server will crack. 
>Fix:

>Release-Note:
>Audit-Trail:

From: zhouyi zhou <zhouyi04@ios.cn>
To: bug-followup@FreeBSD.org
Cc: zhouyi04@ios.cn
Subject: (Resolved) Re: kern/94599: [mac] MAC (Mandatory Access Control) and
 IPSEC can not coexist
Date: Tue, 21 Mar 2006 11:50:54 +0800

 FreeBSD release 5.4 to 6.0 exists serious bugs,
 when IPSEC and MAC configured togethor (the system will crash).
 
 The reason is follows:
 277 m_move_pkthdr(struct mbuf *to, struct mbuf *from)
 278 {
 279 
 280 #if 0
 281         /* see below for why these are not enabled */
 282         M_ASSERTPKTHDR(to);
 283         /* Note: with MAC, this may not be a good assertion. */
 284         KASSERT(SLIST_EMPTY(&to->m_pkthdr.tags),
 285             ("m_move_pkthdr: to has tags"));
 286 #endif
 287 #ifdef MAC
 288         /*
 289          * XXXMAC: It could be this should also occur for non-MAC?
 290          */
 291         if (to->m_flags & M_PKTHDR)
 292                 m_tag_delete_chain(to, NULL);
 293 #endif
 294         to->m_flags = (from->m_flags & M_COPYFLAGS) | (to->m_flags & M_EXT);
 295         if ((to->m_flags & M_EXT) == 0)
 296                 to->m_data = to->m_pktdat;
 297         to->m_pkthdr = from->m_pkthdr;          /* especially tags */
 298         SLIST_INIT(&from->m_pkthdr.tags);       /* purge tags from src */
 299         from->m_flags &= ~M_PKTHDR;
 300 }
 What if on line 292, the mbufs to and from point to the same tag list?
 
 The method to resolve:
 1simply comments out line 292
 2compare if mbufs to and from point to the same tag list
 
 
 Sincerely yours
 Zhouyi Zhou
 Ma Yong
 Wu Xinsong
 Institute of Software
 Chinese Academy of Sciences

From: zhouyi zhou <zhouyi04@ios.cn>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/94599: [mac] MAC (Mandatory Access Control) and IPSEC can
 not coexist
Date: Sun, 26 Mar 2006 11:06:17 +0800

 I reexamined the cause of the conflict between MAC and IPSEC.
 The reason is the perform of m_tag_delete_chain(to, NULL) will
 cause IPSEC to do something bad to mbuf's label.
 
 And you can  comments out the m_tag_delete_chain in
  function m_move_pkthdr and m_dup_pkthdr.
 And do follows to not allocate MAC label to the mbufs act as "to" in m_move_pkthdr
 , and m_dup_pkthdr:
 
 static int
 mb_ctor_mbuf(void *mem, int size, void *arg, int how)
 {
         struct mbuf *m;
         struct mb_args *args;
 #ifdef MAC
         int error;
 #endif
         int flags;
         short type;
 
 #ifdef INVARIANTS
         trash_ctor(mem, size, arg, how);
 #endif
         m = (struct mbuf *)mem;
         args = (struct mb_args *)arg;
         flags = args->flags;
         type = args->type;
 
         m->m_type = type;
         m->m_next = NULL;
         m->m_nextpkt = NULL;
         m->m_flags = flags;
         if (flags & M_PKTHDR) {
                 m->m_data = m->m_pktdat;
                 m->m_pkthdr.rcvif = NULL;
                 m->m_pkthdr.csum_flags = 0;
                SLIST_INIT(&m->m_pkthdr.tags);
 #ifdef MAC
                 /* If the label init fails, fail the alloc */
                 if(!(flags&M_PROTO1)){
                 error = mac_init_mbuf(m, how);
                 if (error)
                         return (error);
                 }
 #endif
         } else
                 m->m_data = m->m_dat;
         mbstat.m_mbufs += 1;    /* XXX */
         return (0);
 }
 
 and 
 
 mb_ctor_pack(void *mem, int size, void *arg, int how)
 {
         struct mbuf *m;
         struct mb_args *args;
 #ifdef MAC
         int error;
 #endif
         int flags;
         short type;
 
         m = (struct mbuf *)mem;
         args = (struct mb_args *)arg;
         flags = args->flags;
         type = args->type;
 
 #ifdef INVARIANTS
         trash_ctor(m->m_ext.ext_buf, MCLBYTES, arg, how);
 #endif
         m->m_type = type;
         m->m_next = NULL;
         m->m_nextpkt = NULL;
         m->m_data = m->m_ext.ext_buf;
         m->m_flags = flags|M_EXT;
         m->m_ext.ext_free = NULL;
         m->m_ext.ext_args = NULL;
         m->m_ext.ext_size = MCLBYTES;
         m->m_ext.ext_type = EXT_PACKET;
         m->m_ext.ref_cnt = NULL;        /* Lazy counter assign. */
 
         if (flags & M_PKTHDR) {
                 m->m_pkthdr.rcvif = NULL;
                 m->m_pkthdr.csum_flags = 0;
                 SLIST_INIT(&m->m_pkthdr.tags);
 #ifdef MAC
                 /* If the label init fails, fail the alloc */
                 if(!(flags&M_PROTO1)){
                 error = mac_init_mbuf(m, how);
                 if (error)
                         return (error);
                 }
 
 #endif
         }
         mbstat.m_mbufs += 1;    /* XXX */
         mbstat.m_mclusts += 1;  /* XXX */
         return (0);
 }
 
 And in very place there is a m_move_pkthdr or m_dup_pkthdr:
 For example in function m_defrag in uipc_mbuf.c 
         if (m0->m_pkthdr.len > MHLEN)
                 m_final = m_getcl(how, MT_DATA, M_PKTHDR|M_PROTO1);
         else
                 m_final = m_gethdrnolabel(how, MT_DATA);
 
         if (m_final == NULL)
                 goto nospace;
 
         if (m_dup_pkthdr(m_final, m0, how) == 0)
                 goto nospace;
 // The definition of m_gethdrnolabel is as follows:
 struct mbuf *
 m_gethdrnolabel(int how, short type)
 {
         struct mb_args args;
 
         args.flags = M_PKTHDR|M_PROTO1;
         args.type = type;
         return (uma_zalloc_arg(zone_mbuf, &args, how));
 }
 
 

From: zhouyi zhou <zhouyi04@ios.cn>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/94599: [mac] MAC (Mandatory Access Control) and IPSEC can
 not coexist
Date: Tue, 28 Mar 2006 08:51:13 +0800

 I finally find reason why.
 
  there exists a serious bug in function ipsec_copypkt(m) 
 of netinet6/ipsec.c in FreeBSD 5.4, FreeBSD 6.0 and FreeBSD 7.0
 
 3469                                         MGETHDR(mnew, M_DONTWAIT, MT_HEADER);
 3470                                         if (mnew == NULL)
 3471                                                 goto fail;
 3472                                         mnew->m_pkthdr = n->m_pkthdr;
 3473 #if 0
 3474                                         /* XXX: convert to m_tag or delete? */
 3475                                         if (n->m_pkthdr.aux) {
 3476                                                 mnew->m_pkthdr.aux =
 3477                                                     m_copym(n->m_pkthdr.aux,
 3478                                                     0, M_COPYALL, M_DONTWAIT);
 3479                                         }
 3480 #endif
 3481                                         M_MOVE_PKTHDR(mnew, n);
 
 On line 3472, mnew->m_pkthdr is assigned n->m_pkthdr, and 
 on line 3481, in function m_move_pkthdr, mnew's tag list will be delete (and the n's tag 
 of cause). This will cause system to crash.
 
 After commenting out line 3472, everything is OK.
 
 
 Sincerely yours
 Zhouyi Zhou
 Institute of Software
 Chinese Academy of Sciences
State-Changed-From-To: open->patched 
State-Changed-By: rwatson 
State-Changed-When: Tue Mar 28 10:05:54 UTC 2006 
State-Changed-Why:  
Proposed fix merged as ipsec.c:1.44, will be MFC'd for 5.5 and 6.1 with 
approval of release engineer (requested). 



Responsible-Changed-From-To: freebsd-bugs->rwatson 
Responsible-Changed-By: rwatson 
Responsible-Changed-When: Tue Mar 28 10:05:54 UTC 2006 
Responsible-Changed-Why:  
Take ownership since I have an interest in MAC issues.  Have been running 
patches by bz@ also. 


http://www.freebsd.org/cgi/query-pr.cgi?pr=94599 
State-Changed-From-To: patched->feedback 
State-Changed-By: rwatson 
State-Changed-When: Sun Apr 2 11:23:59 UTC 2006 
State-Changed-Why:  
This was fixed in ipsec.c:1.44, and was MFC'd to RELENG_6 as 
ipsec.c:1.42.2.2 and RELENG_5 as ipsec.c:1.36.2.5.  If you could confirm 
that the final version of this change does indeed fix this bug, I can 
close the PR. 

Thanks for the excellent analysis -- this would have taken a while to 
track down! 


http://www.freebsd.org/cgi/query-pr.cgi?pr=94599 
State-Changed-From-To: feedback->closed 
State-Changed-By: rwatson 
State-Changed-When: Mon Apr 3 09:02:11 UTC 2006 
State-Changed-Why:  
Submitter has reported problem is indeed fixed, closing this PR. 

Thanks 


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