Introduce a m_verify_packet function, that verifies the mbuf chain of a
packet to ensure it is not malformed. Call this function in "points of interest", that are the IPv4/IPv6/IPsec entry points. There could be more. We use M_VERIFY_PACKET(m), declared under DIAGNOSTIC only. This function should not be called everywhere, especially not in places that temporarily manipulate (and clobber) the mbuf structure; once they're done they put the mbuf back in a correct format.
This commit is contained in:
parent
dfb49eea50
commit
f75d3c0566
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: uipc_mbuf.c,v 1.187 2018/04/10 16:12:30 maxv Exp $ */
|
||||
/* $NetBSD: uipc_mbuf.c,v 1.188 2018/04/15 07:35:49 maxv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999, 2001 The NetBSD Foundation, Inc.
|
||||
|
@ -62,7 +62,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.187 2018/04/10 16:12:30 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.188 2018/04/15 07:35:49 maxv Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_mbuftrace.h"
|
||||
|
@ -1888,6 +1888,67 @@ m_claim(struct mbuf *m, struct mowner *mo)
|
|||
}
|
||||
#endif /* defined(MBUFTRACE) */
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
/*
|
||||
* Verify that the mbuf chain is not malformed. Used only for diagnostic.
|
||||
* Panics on error.
|
||||
*/
|
||||
void
|
||||
m_verify_packet(struct mbuf *m)
|
||||
{
|
||||
struct mbuf *n = m;
|
||||
char *low, *high, *dat;
|
||||
int totlen = 0, len;
|
||||
|
||||
if (__predict_false((m->m_flags & M_PKTHDR) == 0)) {
|
||||
panic("%s: mbuf doesn't have M_PKTHDR", __func__);
|
||||
}
|
||||
|
||||
while (n != NULL) {
|
||||
if (__predict_false(n->m_type == MT_FREE)) {
|
||||
panic("%s: mbuf already freed (n = %p)", __func__, n);
|
||||
}
|
||||
if (__predict_false((n != m) && (n->m_flags & M_PKTHDR) != 0)) {
|
||||
panic("%s: M_PKTHDR set on secondary mbuf", __func__);
|
||||
}
|
||||
if (__predict_false(n->m_nextpkt != NULL)) {
|
||||
panic("%s: m_nextpkt not null (m_nextpkt = %p)",
|
||||
__func__, n->m_nextpkt);
|
||||
}
|
||||
|
||||
dat = n->m_data;
|
||||
len = n->m_len;
|
||||
|
||||
if (n->m_flags & M_EXT) {
|
||||
low = n->m_ext.ext_buf;
|
||||
high = low + n->m_ext.ext_size;
|
||||
} else if (n->m_flags & M_PKTHDR) {
|
||||
low = n->m_pktdat;
|
||||
high = low + MHLEN;
|
||||
} else {
|
||||
low = n->m_dat;
|
||||
high = low + MLEN;
|
||||
}
|
||||
if (__predict_false(dat + len <= dat)) {
|
||||
panic("%s: incorrect length (len = %d)", __func__, len);
|
||||
}
|
||||
if (__predict_false((dat < low) || (dat + len > high))) {
|
||||
panic("%s: m_data not in packet"
|
||||
"(dat = %p, len = %d, low = %p, high = %p)",
|
||||
__func__, dat, len, low, high);
|
||||
}
|
||||
|
||||
totlen += len;
|
||||
n = n->m_next;
|
||||
}
|
||||
|
||||
if (__predict_false(totlen != m->m_pkthdr.len)) {
|
||||
panic("%s: inconsistent mbuf length (%d != %d)", __func__,
|
||||
totlen, m->m_pkthdr.len);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Release a reference to the mbuf external storage.
|
||||
*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ip_input.c,v 1.379 2018/04/11 08:11:20 maxv Exp $ */
|
||||
/* $NetBSD: ip_input.c,v 1.380 2018/04/15 07:35:49 maxv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -91,7 +91,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.379 2018/04/11 08:11:20 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.380 2018/04/15 07:35:49 maxv Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_inet.h"
|
||||
|
@ -766,6 +766,8 @@ ours:
|
|||
hlen = ip->ip_hl << 2;
|
||||
}
|
||||
|
||||
M_VERIFY_PACKET(m);
|
||||
|
||||
#ifdef IPSEC
|
||||
/*
|
||||
* Enforce IPsec policy checking if we are seeing last header.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ip6_input.c,v 1.196 2018/04/11 07:55:19 maxv Exp $ */
|
||||
/* $NetBSD: ip6_input.c,v 1.197 2018/04/15 07:35:49 maxv Exp $ */
|
||||
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -62,7 +62,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.196 2018/04/11 07:55:19 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.197 2018/04/15 07:35:49 maxv Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_gateway.h"
|
||||
|
@ -748,6 +748,8 @@ hbhcheck:
|
|||
goto bad;
|
||||
}
|
||||
|
||||
M_VERIFY_PACKET(m);
|
||||
|
||||
/*
|
||||
* protection against faulty packet - there should be
|
||||
* more sanity checks in header chain processing.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ipsec_input.c,v 1.62 2018/02/26 09:04:29 maxv Exp $ */
|
||||
/* $NetBSD: ipsec_input.c,v 1.63 2018/04/15 07:35:49 maxv Exp $ */
|
||||
/* $FreeBSD: src/sys/netipsec/ipsec_input.c,v 1.2.4.2 2003/03/28 20:32:53 sam Exp $ */
|
||||
/* $OpenBSD: ipsec_input.c,v 1.63 2003/02/20 18:35:43 deraadt Exp $ */
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipsec_input.c,v 1.62 2018/02/26 09:04:29 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipsec_input.c,v 1.63 2018/04/15 07:35:49 maxv Exp $");
|
||||
|
||||
/*
|
||||
* IPsec input processing.
|
||||
|
@ -456,6 +456,8 @@ cantpull:
|
|||
#endif /* INET6 */
|
||||
#endif /* notyet */
|
||||
|
||||
M_VERIFY_PACKET(m);
|
||||
|
||||
key_sa_recordxfer(sav, m); /* record data transfer */
|
||||
|
||||
if ((inetsw[ip_protox[prot]].pr_flags & PR_LASTHDR) != 0 &&
|
||||
|
@ -667,6 +669,8 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
|
|||
goto bad;
|
||||
}
|
||||
|
||||
M_VERIFY_PACKET(m);
|
||||
|
||||
/*
|
||||
* Protection against faulty packet - there should be
|
||||
* more sanity checks in header chain processing.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mbuf.h,v 1.185 2018/04/13 08:44:41 maxv Exp $ */
|
||||
/* $NetBSD: mbuf.h,v 1.186 2018/04/15 07:35:49 maxv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997, 1999, 2001, 2007 The NetBSD Foundation, Inc.
|
||||
|
@ -704,6 +704,12 @@ do { \
|
|||
(m)->m_type = t; \
|
||||
} while (/* CONSTCOND */ 0)
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
#define M_VERIFY_PACKET(m) m_verify_packet(m)
|
||||
#else
|
||||
#define M_VERIFY_PACKET(m) /* nothing */
|
||||
#endif
|
||||
|
||||
/* length to m_copy to copy all */
|
||||
#define M_COPYALL -1
|
||||
|
||||
|
@ -864,6 +870,7 @@ struct mbuf *m_copyback_cow(struct mbuf *, int, int, const void *, int);
|
|||
int m_makewritable(struct mbuf **, int, int, int);
|
||||
struct mbuf *m_getcl(int, int, int);
|
||||
void m_copydata(struct mbuf *, int, int, void *);
|
||||
void m_verify_packet(struct mbuf *);
|
||||
struct mbuf *m_free(struct mbuf *);
|
||||
void m_freem(struct mbuf *);
|
||||
void m_reclaim(void *, int);
|
||||
|
|
Loading…
Reference in New Issue