X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/1c79356b52d46aa6b508fb032f5ae709b1f2897b..5eebf7385fedb1517b66b53c28e5aa6bb0a2be50:/bsd/kern/uipc_usrreq.c diff --git a/bsd/kern/uipc_usrreq.c b/bsd/kern/uipc_usrreq.c index 480bc28f8..dda829231 100644 --- a/bsd/kern/uipc_usrreq.c +++ b/bsd/kern/uipc_usrreq.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2001 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -502,7 +502,7 @@ unp_attach(so) if (error) return (error); } - unp = zalloc(unp_zone); + unp = (struct unpcb*)zalloc(unp_zone); if (unp == NULL) return (ENOBUFS); bzero(unp, sizeof *unp); @@ -524,11 +524,12 @@ unp_detach(unp) unp->unp_gencnt = ++unp_gencnt; --unp_count; if (unp->unp_vnode) { + struct vnode *tvp = unp->unp_vnode; unp->unp_vnode->v_socket = 0; + unp->unp_vnode = 0; thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL); - vrele(unp->unp_vnode); + vrele(tvp); thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); - unp->unp_vnode = 0; } if (unp->unp_conn) unp_disconnect(unp); @@ -549,7 +550,7 @@ unp_detach(unp) } if (unp->unp_addr) FREE(unp->unp_addr, M_SONAME); - zfree(unp_zone, unp); + zfree(unp_zone, (vm_offset_t)unp); } static int @@ -567,7 +568,6 @@ unp_bind(unp, nam, p) if (unp->unp_vnode != NULL) return (EINVAL); -#define offsetof(s, e) ((char *)&((s *)0)->e - (char *)((s *)0)) namelen = soun->sun_len - offsetof(struct sockaddr_un, sun_path); if (namelen <= 0) return EINVAL; @@ -660,6 +660,18 @@ unp_connect(so, nam, p) goto bad; } thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); + + /* + * Check if socket was connected while we were trying to + * acquire the funnel. + * XXX - probably shouldn't return an error for SOCK_DGRAM + */ + if ((so->so_state & SS_ISCONNECTED) != 0) { + error = EISCONN; + thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL); + goto bad; + } + if (so->so_proto->pr_flags & PR_CONNREQUIRED) { if ((so2->so_options & SO_ACCEPTCONN) == 0 || (so3 = sonewconn(so2, 0)) == 0) { @@ -694,6 +706,11 @@ unp_connect2(so, so2) if (so2->so_type != so->so_type) return (EPROTOTYPE); unp2 = sotounpcb(so2); + + /* Verify both sockets are still opened */ + if (unp == 0 || unp2 == 0) + return (EINVAL); + unp->unp_conn = unp2; switch (so->so_type) { @@ -787,6 +804,12 @@ unp_pcblist SYSCTL_HANDLER_ARGS if (error) return error; + /* + * We are done if there is no pcb + */ + if (n == 0) + return 0; + unp_list = _MALLOC(n * sizeof *unp_list, M_TEMP, M_WAITOK); if (unp_list == 0) return ENOMEM; @@ -872,7 +895,7 @@ unp_drop(unp, errno) so->so_pcb = (caddr_t) 0; if (unp->unp_addr) FREE(unp->unp_addr, M_SONAME); - zfree(unp_zone, unp); + zfree(unp_zone, (vm_offset_t)unp); sofree(so); } } @@ -924,6 +947,7 @@ unp_externalize(rights) panic("unp_externalize"); fp = *rp; p->p_fd->fd_ofiles[f] = fp; + *fdflags(p, f) &= ~UF_RESERVED; fp->f_msgcount--; unp_rights--; *(int *)rp++ = f;