m_tag_delete_chain do something bad in FreeBSD MAC Framework and
IPSEC confliction
zhouyi zhou
zhouyi04 at ios.cn
Sun Mar 26 03:17:10 UTC 2006
Dear Colleques:
I reexamined the cause of the conflict between MAC and IPSEC.
The reason is the perform of m_tag_delete_chain(to, NULL) in functions
m_move_pkthdr and m_dup_pkthdr 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));
}
Sincerely
Zhouyi Zhou
Institute of Software
Chinese Academy of Sciences
More information about the freebsd-bugs
mailing list