Index: uipc_usrreq.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v retrieving revision 1.97 diff -u -p -r1.97 uipc_usrreq.c --- uipc_usrreq.c 25 Apr 2016 20:18:31 -0000 1.97 +++ uipc_usrreq.c 12 Jul 2016 00:12:13 -0000 @@ -61,6 +61,7 @@ LIST_HEAD(unp_head, unpcb) unp_head = LI * not received and need to be closed. */ struct unp_deferral { + unsigned long ud_cksum; SLIST_ENTRY(unp_deferral) ud_link; int ud_n; /* followed by ud_n struct file * pointers */ @@ -882,15 +883,18 @@ fail: } int unp_defer, unp_gcing; +unsigned int unp_defers = 0; void unp_gc(void *arg __unused) { struct unp_deferral *defer; + struct file **fps; struct file *fp; struct socket *so; struct unpcb *unp; int nunref, i; + unsigned long cksum; if (unp_gcing) return; @@ -899,16 +903,26 @@ unp_gc(void *arg __unused) /* close any fds on the deferred list */ while ((defer = SLIST_FIRST(&unp_deferred)) != NULL) { SLIST_REMOVE_HEAD(&unp_deferred, ud_link); + printf("%s: defer %p n %d cksum %lx\n", __func__, + defer, defer->ud_n, defer->ud_cksum); + cksum = 0; + fps = (struct file **)(defer + 1); for (i = 0; i < defer->ud_n; i++) { - memcpy(&fp, &((struct file **)(defer + 1))[i], - sizeof(fp)); + fp = fps[i]; + cksum ^= (unsigned long)fps[i]; + FREF(fp); if ((unp = fptounp(fp)) != NULL) unp->unp_msgcount--; unp_rights--; (void) closef(fp, NULL); } + if (cksum != defer->ud_cksum) { + panic("cksum %lx != defer %p cksum %lx", cksum, + defer, defer->ud_cksum); + } free(defer, M_TEMP, sizeof(*defer) + sizeof(fp) * defer->ud_n); + unp_defers++; } unp_defer = 0; @@ -1057,12 +1071,25 @@ void unp_discard(struct file **rp, int nfds) { struct unp_deferral *defer; + struct file **fps; + unsigned long cksum = 0; + unsigned int i; /* copy the file pointers to a deferral structure */ defer = malloc(sizeof(*defer) + sizeof(*rp) * nfds, M_TEMP, M_WAITOK); defer->ud_n = nfds; - memcpy(defer + 1, rp, sizeof(*rp) * nfds); + + fps = (struct file **)(defer + 1); + for (i = 0; i < nfds; i++) { + KASSERT(rp[i] != NULL); + fps[i] = rp[i]; + cksum ^= (unsigned long)rp[i]; + } + defer->ud_cksum = cksum; + memset(rp, 0, sizeof(*rp) * nfds); + printf("%s: defer %p n %d cksum %lx\n", __func__, defer, defer->ud_n, + defer->ud_cksum); SLIST_INSERT_HEAD(&unp_deferred, defer, ud_link); task_add(systq, &unp_gc_task);