Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-2-0]: src/sys/kern Pull up revision 1.64 (requested by jonathan i...
details: https://anonhg.NetBSD.org/src/rev/7a6c6da8bfaf
branches: netbsd-2-0
changeset: 561408:7a6c6da8bfaf
user: tron <tron%NetBSD.org@localhost>
date: Wed Jun 16 18:10:32 2004 +0000
description:
Pull up revision 1.64 (requested by jonathan in ticket #503):
Fix potential memory leak in sbappendaddrchain():
We do an MGETHDR)() for each mbuf "packet" of the input chain, to hold
the socket address prepended to that "packet". If those MGETHDR()s
ever failed, we would leak all the successfully-allocated mbuf
headers. Leak noted by Yamamoto-san (yamt%NetBSD.org@localhost); thanks for catching it!
Add socketbuf invariant-checking macros to sbappendaddrchain(), and
replace a stray bcopy() with memcpy(), also as suggested by Yamamoto-san.
diffstat:
sys/kern/uipc_socket2.c | 59 ++++++++++++++++++++++++++++++++++++++----------
1 files changed, 46 insertions(+), 13 deletions(-)
diffs (112 lines):
diff -r 1b46ac18ad63 -r 7a6c6da8bfaf sys/kern/uipc_socket2.c
--- a/sys/kern/uipc_socket2.c Tue Jun 15 23:18:40 2004 +0000
+++ b/sys/kern/uipc_socket2.c Wed Jun 16 18:10:32 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uipc_socket2.c,v 1.58.2.1 2004/05/30 07:02:16 tron Exp $ */
+/* $NetBSD: uipc_socket2.c,v 1.58.2.2 2004/06/16 18:10:32 tron Exp $ */
/*
* Copyright (c) 1982, 1986, 1988, 1990, 1993
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.58.2.1 2004/05/30 07:02:16 tron Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.58.2.2 2004/06/16 18:10:32 tron Exp $");
#include "opt_mbuftrace.h"
#include "opt_sb_max.h"
@@ -760,22 +760,32 @@
* an mbuf chain.
*/
static __inline struct mbuf *
-m_prepend_sockaddr(struct mbuf *m0, const struct sockaddr *asa)
+m_prepend_sockaddr(struct sockbuf *sb, struct mbuf *m0,
+ const struct sockaddr *asa)
{
struct mbuf *m;
- const int mlen = asa->sa_len;
+ const int salen = asa->sa_len;
/* only the first in each chain need be a pkthdr */
MGETHDR(m, M_DONTWAIT, MT_SONAME);
if (m == 0)
return (0);
MCLAIM(m, sb->sb_mowner);
- KASSERT(mlen <= MLEN);
-
- m->m_len = mlen;
- bcopy((caddr_t)asa, mtod(m, caddr_t), mlen);
+#ifdef notyet
+ if (salen > MHLEN) {
+ MEXTMALLOC(m, salen, M_NOWAIT);
+ if ((m->m_flags & M_EXT) == 0) {
+ m_free(m);
+ return (0);
+ }
+ }
+#else
+ KASSERT(salen <= MHLEN);
+#endif
+ m->m_len = salen;
+ memcpy(mtod(m, caddr_t), (caddr_t)asa, salen);
m->m_next = m0;
- m->m_pkthdr.len = mlen + m0->m_pkthdr.len;
+ m->m_pkthdr.len = salen + m0->m_pkthdr.len;
return m;
}
@@ -819,8 +829,12 @@
for (m = m0; m; m = m->m_nextpkt) {
struct mbuf *np;
+#ifdef MBUFTRACE
+ m_claim(m, sb->sb_mowner);
+#endif
+
/* Prepend sockaddr to this record (m) of input chain m0 */
- n = m_prepend_sockaddr(m, asa);
+ n = m_prepend_sockaddr(sb, m, asa);
if (n == NULL) {
error = ENOBUFS;
goto bad;
@@ -839,17 +853,36 @@
sballoc(sb, np);
}
+ SBLASTRECORDCHK(sb, "sbappendaddrchain 1");
+
/* Drop the entire chain of (asa+m) records onto the socket */
SBLINKRECORDCHAIN(sb, n0, nlast);
+
+ SBLASTRECORDCHK(sb, "sbappendaddrchain 2");
+
for (m = nlast; m->m_next; m = m->m_next)
;
sb->sb_mbtail = m;
-
+ SBLASTMBUFCHK(sb, "sbappendaddrchain");
+
return (1);
bad:
- if (n)
- m_freem(n);
+ /*
+ * On error, free the prepended addreseses. For consistency
+ * with sbappendaddr(), leave it to our caller to free
+ * the input record chain passed to us as m0.
+ */
+ while ((n = n0) != NULL) {
+ struct mbuf *np;
+
+ /* Undo the sballoc() of this record */
+ for (np = n; np; np = np->m_next)
+ sbfree(sb, np);
+
+ n0 = n->m_nextpkt; /* iterate at next prepended address */
+ MFREE(n, np); /* free prepended address (not data) */
+ }
return 0;
}
Home |
Main Index |
Thread Index |
Old Index