Author: pjd Date: Mon Mar 11 22:59:07 2013 New Revision: 248176 URL: http://svnweb.freebsd.org/changeset/base/248176
Log: Fix memory leak when one process send descriptor over UNIX domain socket, but the other process exited before receiving it. Modified: head/sys/kern/uipc_usrreq.c Modified: head/sys/kern/uipc_usrreq.c ============================================================================== --- head/sys/kern/uipc_usrreq.c Mon Mar 11 22:17:39 2013 (r248175) +++ head/sys/kern/uipc_usrreq.c Mon Mar 11 22:59:07 2013 (r248176) @@ -282,7 +282,7 @@ static void unp_dispose(struct mbuf *); static void unp_shutdown(struct unpcb *); static void unp_drop(struct unpcb *, int); static void unp_gc(__unused void *, int); -static void unp_scan(struct mbuf *, void (*)(struct file *)); +static void unp_scan(struct mbuf *, void (*)(struct filedescent **, int)); static void unp_discard(struct file *); static void unp_freerights(struct filedescent **, int); static void unp_init(void); @@ -2135,17 +2135,22 @@ static int unp_marked; static int unp_unreachable; static void -unp_accessable(struct file *fp) +unp_accessable(struct filedescent **fdep, int fdcount) { struct unpcb *unp; + struct file *fp; + int i; - if ((unp = fptounp(fp)) == NULL) - return; - if (unp->unp_gcflag & UNPGC_REF) - return; - unp->unp_gcflag &= ~UNPGC_DEAD; - unp->unp_gcflag |= UNPGC_REF; - unp_marked++; + for (i = 0; i < fdcount; i++) { + fp = fdep[i]->fde_file; + if ((unp = fptounp(fp)) == NULL) + continue; + if (unp->unp_gcflag & UNPGC_REF) + continue; + unp->unp_gcflag &= ~UNPGC_DEAD; + unp->unp_gcflag |= UNPGC_REF; + unp_marked++; + } } static void @@ -2292,19 +2297,16 @@ unp_dispose(struct mbuf *m) { if (m) - unp_scan(m, unp_discard); + unp_scan(m, unp_freerights); } static void -unp_scan(struct mbuf *m0, void (*op)(struct file *)) +unp_scan(struct mbuf *m0, void (*op)(struct filedescent **, int)) { struct mbuf *m; - struct filedescent **fdep; struct cmsghdr *cm; void *data; - int i; socklen_t clen, datalen; - int qfds; while (m0 != NULL) { for (m = m0; m; m = m->m_next) { @@ -2324,10 +2326,8 @@ unp_scan(struct mbuf *m0, void (*op)(str if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS) { - qfds = datalen / sizeof(*fdep); - fdep = data; - for (i = 0; i < qfds; i++) - (*op)(fdep[i]->fde_file); + (*op)(data, datalen / + sizeof(struct filedescent *)); } if (CMSG_SPACE(datalen) < clen) { _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"