summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2012-09-26 14:53:24 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2012-09-26 14:53:24 +0000
commit29406fae86e2db0ed2b65d941b4df825cac38a57 (patch)
treefd46af912302b522959ec366138651ea9680cb4a /sys/kern
parent9f5c6dd85375c5bd1a39d6916b959a5b5db13957 (diff)
add M_ZEROIZE as an mbuf flag, so copied PFKEY messages (with embedded keys)
are cleared as well; from hshoexer@, feedback and ok bluhm@, ok claudio@
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/uipc_mbuf.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index 5348f38a930..4ec2bed41f1 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_mbuf.c,v 1.166 2012/04/13 09:38:32 deraadt Exp $ */
+/* $OpenBSD: uipc_mbuf.c,v 1.167 2012/09/26 14:53:23 markus Exp $ */
/* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */
/*
@@ -127,6 +127,7 @@ void m_cltick(void *);
void m_extfree(struct mbuf *);
struct mbuf *m_copym0(struct mbuf *, int, int, int, int);
void nmbclust_update(void);
+void m_zero(struct mbuf *);
const char *mclpool_warnmsg =
@@ -467,11 +468,17 @@ m_free_unlocked(struct mbuf *m)
struct mbuf *n;
mbstat.m_mtypes[m->m_type]--;
+ n = m->m_next;
+ if (m->m_flags & M_ZEROIZE) {
+ m_zero(m);
+ /* propagate M_ZEROIZE to the next mbuf in the chain */
+ if (n)
+ n->m_flags |= M_ZEROIZE;
+ }
if (m->m_flags & M_PKTHDR)
m_tag_delete_chain(m);
if (m->m_flags & M_EXT)
m_extfree(m);
- n = m->m_next;
pool_put(&mbpool, m);
return (n);
@@ -1183,6 +1190,11 @@ m_devget(char *buf, int totlen, int off, struct ifnet *ifp,
if (top != NULL) {
MGET(m, M_DONTWAIT, MT_DATA);
if (m == NULL) {
+ /*
+ * As we might get called by pfkey, make sure
+ * we do not leak sensitive data.
+ */
+ top->m_flags |= M_ZEROIZE;
m_freem(top);
return (NULL);
}
@@ -1225,20 +1237,18 @@ m_devget(char *buf, int totlen, int off, struct ifnet *ifp,
void
m_zero(struct mbuf *m)
{
- while (m) {
#ifdef DIAGNOSTIC
- if (M_READONLY(m))
- panic("m_zero: M_READONLY");
+ if (M_READONLY(m))
+ panic("m_zero: M_READONLY");
#endif /* DIAGNOSTIC */
- if (m->m_flags & M_EXT)
- memset(m->m_ext.ext_buf, 0, m->m_ext.ext_size);
- else {
- if (m->m_flags & M_PKTHDR)
- memset(m->m_pktdat, 0, MHLEN);
- else
- memset(m->m_dat, 0, MLEN);
- }
- m = m->m_next;
+
+ if (m->m_flags & M_EXT)
+ explicit_bzero(m->m_ext.ext_buf, m->m_ext.ext_size);
+ else {
+ if (m->m_flags & M_PKTHDR)
+ explicit_bzero(m->m_pktdat, MHLEN);
+ else
+ explicit_bzero(m->m_dat, MLEN);
}
}
@@ -1339,7 +1349,7 @@ m_print(void *v, int (*pr)(const char *, ...))
(*pr)("m_type: %hi\tm_flags: %b\n", m->m_type, m->m_flags,
"\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_CLUSTER\5M_PROTO1\6M_VLANTAG"
"\7M_LOOP\10M_FILDROP\11M_BCAST\12M_MCAST\13M_CONF\14M_AUTH"
- "\15M_TUNNEL\16M_AUTH_AH\17M_LINK0");
+ "\15M_TUNNEL\16M_ZEROIZE\17M_LINK0");
(*pr)("m_next: %p\tm_nextpkt: %p\n", m->m_next, m->m_nextpkt);
(*pr)("m_data: %p\tm_len: %u\n", m->m_data, m->m_len);
(*pr)("m_dat: %p m_pktdat: %p\n", m->m_dat, m->m_pktdat);