X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d9a64523371fa019c4575bb400cbbc3a50ac9903..c6bf4f310a33a9262d455ea4d3f0630b1255e3fe:/bsd/kern/uipc_usrreq.c?ds=sidebyside diff --git a/bsd/kern/uipc_usrreq.c b/bsd/kern/uipc_usrreq.c index 16a044f7f..2c4434dc2 100644 --- a/bsd/kern/uipc_usrreq.c +++ b/bsd/kern/uipc_usrreq.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2015 Apple Inc. All rights reserved. + * Copyright (c) 2000-2019 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -71,7 +71,7 @@ #include #include #include -#include /* XXX must be before */ +#include /* XXX must be before */ #include #include #include @@ -103,28 +103,28 @@ /* * Maximum number of FDs that can be passed in an mbuf */ -#define UIPC_MAX_CMSG_FD 512 - -#define f_msgcount f_fglob->fg_msgcount -#define f_cred f_fglob->fg_cred -#define f_ops f_fglob->fg_ops -#define f_offset f_fglob->fg_offset -#define f_data f_fglob->fg_data -struct zone *unp_zone; -static unp_gen_t unp_gencnt; -static u_int unp_count; - -static lck_attr_t *unp_mtx_attr; -static lck_grp_t *unp_mtx_grp; -static lck_grp_attr_t *unp_mtx_grp_attr; -static lck_rw_t *unp_list_mtx; - -static lck_mtx_t *unp_disconnect_lock; -static lck_mtx_t *unp_connect_lock; +#define UIPC_MAX_CMSG_FD 512 + +#define f_msgcount f_fglob->fg_msgcount +#define f_cred f_fglob->fg_cred +#define f_ops f_fglob->fg_ops +#define f_offset f_fglob->fg_offset +#define f_data f_fglob->fg_data +struct zone *unp_zone; +static unp_gen_t unp_gencnt; +static u_int unp_count; + +static lck_attr_t *unp_mtx_attr; +static lck_grp_t *unp_mtx_grp; +static lck_grp_attr_t *unp_mtx_grp_attr; +static lck_rw_t *unp_list_mtx; + +static lck_mtx_t *unp_disconnect_lock; +static lck_mtx_t *unp_connect_lock; static u_int disconnect_in_progress; extern lck_mtx_t *uipc_lock; -static struct unp_head unp_shead, unp_dhead; +static struct unp_head unp_shead, unp_dhead; /* * mDNSResponder tracing. When enabled, endpoints connected to @@ -134,11 +134,11 @@ static struct unp_head unp_shead, unp_dhead; * to the data itself; this assumes ipc_msg_hdr in dnssd_ipc.h * of mDNSResponder stays the same. */ -#define MDNSRESPONDER_PATH "/var/run/mDNSResponder" +#define MDNSRESPONDER_PATH "/var/run/mDNSResponder" -static int unpst_tracemdns; /* enable tracing */ +static int unpst_tracemdns; /* enable tracing */ -#define MDNS_IPC_MSG_HDR_VERSION_1 1 +#define MDNS_IPC_MSG_HDR_VERSION_1 1 struct mdns_ipc_msg_hdr { uint32_t version; @@ -161,23 +161,23 @@ struct mdns_ipc_msg_hdr { * need a proper out-of-band * lock pushdown */ -static struct sockaddr sun_noname = { sizeof (sun_noname), AF_LOCAL, { 0 } }; -static ino_t unp_ino; /* prototype for fake inode numbers */ - -static int unp_attach(struct socket *); -static void unp_detach(struct unpcb *); -static int unp_bind(struct unpcb *, struct sockaddr *, proc_t); -static int unp_connect(struct socket *, struct sockaddr *, proc_t); -static void unp_disconnect(struct unpcb *); -static void unp_shutdown(struct unpcb *); -static void unp_drop(struct unpcb *, int); -__private_extern__ void unp_gc(void); -static void unp_scan(struct mbuf *, void (*)(struct fileglob *, void *arg), void *arg); -static void unp_mark(struct fileglob *, __unused void *); -static void unp_discard(struct fileglob *, void *); -static int unp_internalize(struct mbuf *, proc_t); -static int unp_listen(struct unpcb *, proc_t); -static void unpcb_to_compat(struct unpcb *, struct unpcb_compat *); +static struct sockaddr sun_noname = { .sa_len = sizeof(sun_noname), .sa_family = AF_LOCAL, .sa_data = { 0 } }; +static ino_t unp_ino; /* prototype for fake inode numbers */ + +static int unp_attach(struct socket *); +static void unp_detach(struct unpcb *); +static int unp_bind(struct unpcb *, struct sockaddr *, proc_t); +static int unp_connect(struct socket *, struct sockaddr *, proc_t); +static void unp_disconnect(struct unpcb *); +static void unp_shutdown(struct unpcb *); +static void unp_drop(struct unpcb *, int); +__private_extern__ void unp_gc(void); +static void unp_scan(struct mbuf *, void (*)(struct fileglob *, void *arg), void *arg); +static void unp_mark(struct fileglob *, __unused void *); +static void unp_discard(struct fileglob *, void *); +static int unp_internalize(struct mbuf *, proc_t); +static int unp_listen(struct unpcb *, proc_t); +static void unpcb_to_compat(struct unpcb *, struct unpcb_compat *); static void unp_get_locks_in_order(struct socket *so, struct socket *conn_so); static void @@ -207,12 +207,13 @@ uipc_abort(struct socket *so) { struct unpcb *unp = sotounpcb(so); - if (unp == 0) - return (EINVAL); + if (unp == 0) { + return EINVAL; + } unp_drop(unp, ECONNABORTED); unp_detach(unp); sofree(so); - return (0); + return 0; } static int @@ -220,8 +221,9 @@ uipc_accept(struct socket *so, struct sockaddr **nam) { struct unpcb *unp = sotounpcb(so); - if (unp == 0) - return (EINVAL); + if (unp == 0) { + return EINVAL; + } /* * Pass back name of connected socket, @@ -234,7 +236,7 @@ uipc_accept(struct socket *so, struct sockaddr **nam) } else { *nam = dup_sockaddr((struct sockaddr *)&sun_noname, 1); } - return (0); + return 0; } /* @@ -247,9 +249,10 @@ uipc_attach(struct socket *so, __unused int proto, __unused proc_t p) { struct unpcb *unp = sotounpcb(so); - if (unp != 0) - return (EISCONN); - return (unp_attach(so)); + if (unp != 0) { + return EISCONN; + } + return unp_attach(so); } static int @@ -257,10 +260,11 @@ uipc_bind(struct socket *so, struct sockaddr *nam, proc_t p) { struct unpcb *unp = sotounpcb(so); - if (unp == 0) - return (EINVAL); + if (unp == 0) { + return EINVAL; + } - return (unp_bind(unp, nam, p)); + return unp_bind(unp, nam, p); } /* @@ -273,9 +277,10 @@ uipc_connect(struct socket *so, struct sockaddr *nam, proc_t p) { struct unpcb *unp = sotounpcb(so); - if (unp == 0) - return (EINVAL); - return (unp_connect(so, nam, p)); + if (unp == 0) { + return EINVAL; + } + return unp_connect(so, nam, p); } /* @@ -289,10 +294,11 @@ uipc_connect2(struct socket *so1, struct socket *so2) { struct unpcb *unp = sotounpcb(so1); - if (unp == 0) - return (EINVAL); + if (unp == 0) { + return EINVAL; + } - return (unp_connect2(so1, so2)); + return unp_connect2(so1, so2); } /* control is EOPNOTSUPP */ @@ -302,12 +308,13 @@ uipc_detach(struct socket *so) { struct unpcb *unp = sotounpcb(so); - if (unp == 0) - return (EINVAL); + if (unp == 0) { + return EINVAL; + } LCK_MTX_ASSERT(&unp->unp_mtx, LCK_MTX_ASSERT_OWNED); unp_detach(unp); - return (0); + return 0; } static int @@ -315,10 +322,11 @@ uipc_disconnect(struct socket *so) { struct unpcb *unp = sotounpcb(so); - if (unp == 0) - return (EINVAL); + if (unp == 0) { + return EINVAL; + } unp_disconnect(unp); - return (0); + return 0; } /* @@ -330,9 +338,10 @@ uipc_listen(struct socket *so, __unused proc_t p) { struct unpcb *unp = sotounpcb(so); - if (unp == 0 || unp->unp_vnode == 0) - return (EINVAL); - return (unp_listen(unp, p)); + if (unp == 0 || unp->unp_vnode == 0) { + return EINVAL; + } + return unp_listen(unp, p); } static int @@ -340,15 +349,16 @@ uipc_peeraddr(struct socket *so, struct sockaddr **nam) { struct unpcb *unp = sotounpcb(so); - if (unp == NULL) - return (EINVAL); + if (unp == NULL) { + return EINVAL; + } if (unp->unp_conn != NULL && unp->unp_conn->unp_addr != NULL) { *nam = dup_sockaddr((struct sockaddr *) unp->unp_conn->unp_addr, 1); } else { *nam = dup_sockaddr((struct sockaddr *)&sun_noname, 1); } - return (0); + return 0; } static int @@ -357,18 +367,20 @@ uipc_rcvd(struct socket *so, __unused int flags) struct unpcb *unp = sotounpcb(so); struct socket *so2; - if (unp == 0) - return (EINVAL); + if (unp == 0) { + return EINVAL; + } switch (so->so_type) { case SOCK_DGRAM: panic("uipc_rcvd DGRAM?"); - /*NOTREACHED*/ + /*NOTREACHED*/ case SOCK_STREAM: -#define rcv (&so->so_rcv) -#define snd (&so2->so_snd) - if (unp->unp_conn == 0) +#define rcv (&so->so_rcv) +#define snd (&so2->so_snd) + if (unp->unp_conn == 0) { break; + } so2 = unp->unp_conn->unp_socket; unp_get_locks_in_order(so, so2); @@ -380,7 +392,9 @@ uipc_rcvd(struct socket *so, __unused int flags) unp->unp_mbcnt = rcv->sb_mbcnt; snd->sb_hiwat += unp->unp_cc - rcv->sb_cc; unp->unp_cc = rcv->sb_cc; - sowwakeup(so2); + if (sb_notify(&so2->so_snd)) { + sowakeup(so2, &so2->so_snd, so); + } socket_unlock(so2, 1); @@ -391,7 +405,7 @@ uipc_rcvd(struct socket *so, __unused int flags) default: panic("uipc_rcvd unknown socktype"); } - return (0); + return 0; } /* pru_rcvoob is EOPNOTSUPP */ @@ -437,8 +451,9 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, socket_unlock(so, 0); error = unp_internalize(control, p); socket_lock(so, 0); - if (error) + if (error) { goto release; + } } switch (so->so_type) { @@ -452,8 +467,9 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, break; } error = unp_connect(so, nam, p); - if (error) + if (error) { break; + } } else { if (unp->unp_conn == 0) { error = ENOTCONN; @@ -462,13 +478,15 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, } so2 = unp->unp_conn->unp_socket; - if (so != so2) + if (so != so2) { unp_get_locks_in_order(so, so2); + } - if (unp->unp_addr) + if (unp->unp_addr) { from = (struct sockaddr *)unp->unp_addr; - else + } else { from = &sun_noname; + } /* * sbappendaddr() will fail when the receiver runs out of * space; in contrast to SOCK_STREAM, we will lose messages @@ -479,25 +497,29 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, */ if (sbappendaddr(&so2->so_rcv, from, m, control, &error)) { control = NULL; - sorwakeup(so2); + if (sb_notify(&so2->so_rcv)) { + sowakeup(so2, &so2->so_rcv, so); + } } else if (control != NULL && error == 0) { /* A socket filter took control; don't touch it */ control = NULL; } - if (so != so2) + if (so != so2) { socket_unlock(so2, 1); + } m = NULL; - if (nam) + if (nam) { unp_disconnect(unp); + } break; } case SOCK_STREAM: { int didreceive = 0; -#define rcv (&so2->so_rcv) -#define snd (&so->so_snd) +#define rcv (&so2->so_rcv) +#define snd (&so->so_snd) /* Connect if not connected yet. */ /* * Note: A better implementation would complain @@ -506,8 +528,9 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, if ((so->so_state & SS_ISCONNECTED) == 0) { if (nam) { error = unp_connect(so, nam, p); - if (error) - break; /* XXX */ + if (error) { + break; /* XXX */ + } } else { error = ENOTCONN; break; @@ -518,8 +541,9 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, error = EPIPE; break; } - if (unp->unp_conn == 0) + if (unp->unp_conn == 0) { panic("uipc_send connected but no connection?"); + } so2 = unp->unp_conn->unp_socket; unp_get_locks_in_order(so, so2); @@ -537,8 +561,8 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, if (unp->unp_flags & UNP_TRACE_MDNS) { struct mdns_ipc_msg_hdr hdr; - if (mbuf_copydata(m, 0, sizeof (hdr), &hdr) == 0 && - hdr.version == ntohl(MDNS_IPC_MSG_HDR_VERSION_1)) { + if (mbuf_copydata(m, 0, sizeof(hdr), &hdr) == 0 && + hdr.version == ntohl(MDNS_IPC_MSG_HDR_VERSION_1)) { printf("%s[mDNSResponder] pid=%d (%s): op=0x%x\n", __func__, p->p_pid, p->p_comm, ntohl(hdr.op)); } @@ -567,7 +591,9 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, unp->unp_conn->unp_cc = rcv->sb_cc; if (didreceive) { control = NULL; - sorwakeup(so2); + if (sb_notify(&so2->so_rcv)) { + sowakeup(so2, &so2->so_rcv, so); + } } else if (control != NULL && error == 0) { /* A socket filter took control; don't touch it */ control = NULL; @@ -577,8 +603,8 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, m = NULL; #undef snd #undef rcv - } - break; + } + break; default: panic("uipc_send unknown socktype"); @@ -600,11 +626,13 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, } release: - if (control) + if (control) { m_freem(control); - if (m) + } + if (m) { m_freem(m); - return (error); + } + return error; } static int @@ -614,16 +642,18 @@ uipc_sense(struct socket *so, void *ub, int isstat64) struct socket *so2; blksize_t blksize; - if (unp == 0) - return (EINVAL); + if (unp == 0) { + return EINVAL; + } blksize = so->so_snd.sb_hiwat; if (so->so_type == SOCK_STREAM && unp->unp_conn != 0) { so2 = unp->unp_conn->unp_socket; blksize += so2->so_rcv.sb_cc; } - if (unp->unp_ino == 0) + if (unp->unp_ino == 0) { unp->unp_ino = unp_ino++; + } if (isstat64 != 0) { struct stat64 *sb64; @@ -641,7 +671,7 @@ uipc_sense(struct socket *so, void *ub, int isstat64) sb->st_ino = (ino_t)(uintptr_t)unp->unp_ino; } - return (0); + return 0; } /* @@ -658,11 +688,12 @@ uipc_shutdown(struct socket *so) { struct unpcb *unp = sotounpcb(so); - if (unp == 0) - return (EINVAL); + if (unp == 0) { + return EINVAL; + } socantsendmore(so); unp_shutdown(unp); - return (0); + return 0; } /* @@ -674,34 +705,35 @@ uipc_sockaddr(struct socket *so, struct sockaddr **nam) { struct unpcb *unp = sotounpcb(so); - if (unp == NULL) - return (EINVAL); + if (unp == NULL) { + return EINVAL; + } if (unp->unp_addr != NULL) { *nam = dup_sockaddr((struct sockaddr *)unp->unp_addr, 1); } else { *nam = dup_sockaddr((struct sockaddr *)&sun_noname, 1); } - return (0); + return 0; } struct pr_usrreqs uipc_usrreqs = { - .pru_abort = uipc_abort, - .pru_accept = uipc_accept, - .pru_attach = uipc_attach, - .pru_bind = uipc_bind, - .pru_connect = uipc_connect, - .pru_connect2 = uipc_connect2, - .pru_detach = uipc_detach, - .pru_disconnect = uipc_disconnect, - .pru_listen = uipc_listen, - .pru_peeraddr = uipc_peeraddr, - .pru_rcvd = uipc_rcvd, - .pru_send = uipc_send, - .pru_sense = uipc_sense, - .pru_shutdown = uipc_shutdown, - .pru_sockaddr = uipc_sockaddr, - .pru_sosend = sosend, - .pru_soreceive = soreceive, + .pru_abort = uipc_abort, + .pru_accept = uipc_accept, + .pru_attach = uipc_attach, + .pru_bind = uipc_bind, + .pru_connect = uipc_connect, + .pru_connect2 = uipc_connect2, + .pru_detach = uipc_detach, + .pru_disconnect = uipc_disconnect, + .pru_listen = uipc_listen, + .pru_peeraddr = uipc_peeraddr, + .pru_rcvd = uipc_rcvd, + .pru_send = uipc_send, + .pru_sense = uipc_sense, + .pru_shutdown = uipc_shutdown, + .pru_sockaddr = uipc_sockaddr, + .pru_sosend = sosend, + .pru_soreceive = soreceive, }; int @@ -718,12 +750,13 @@ uipc_ctloutput(struct socket *so, struct sockopt *sopt) case LOCAL_PEERCRED: if (unp->unp_flags & UNP_HAVEPC) { error = sooptcopyout(sopt, &unp->unp_peercred, - sizeof (unp->unp_peercred)); + sizeof(unp->unp_peercred)); } else { - if (so->so_type == SOCK_STREAM) + if (so->so_type == SOCK_STREAM) { error = ENOTCONN; - else + } else { error = EINVAL; + } } break; case LOCAL_PEERPID: @@ -733,16 +766,18 @@ uipc_ctloutput(struct socket *so, struct sockopt *sopt) break; } peerso = unp->unp_conn->unp_socket; - if (peerso == NULL) + if (peerso == NULL) { panic("peer is connected but has no socket?"); + } unp_get_locks_in_order(so, peerso); if (sopt->sopt_name == LOCAL_PEEREPID && - peerso->so_flags & SOF_DELEGATED) + peerso->so_flags & SOF_DELEGATED) { peerpid = peerso->e_pid; - else + } else { peerpid = peerso->last_pid; + } socket_unlock(peerso, 1); - error = sooptcopyout(sopt, &peerpid, sizeof (peerpid)); + error = sooptcopyout(sopt, &peerpid, sizeof(peerpid)); break; case LOCAL_PEERUUID: case LOCAL_PEEREUUID: @@ -751,16 +786,18 @@ uipc_ctloutput(struct socket *so, struct sockopt *sopt) break; } peerso = unp->unp_conn->unp_socket; - if (peerso == NULL) + if (peerso == NULL) { panic("peer is connected but has no socket?"); + } unp_get_locks_in_order(so, peerso); if (sopt->sopt_name == LOCAL_PEEREUUID && - peerso->so_flags & SOF_DELEGATED) + peerso->so_flags & SOF_DELEGATED) { error = sooptcopyout(sopt, &peerso->e_uuid, - sizeof (peerso->e_uuid)); - else + sizeof(peerso->e_uuid)); + } else { error = sooptcopyout(sopt, &peerso->last_uuid, - sizeof (peerso->last_uuid)); + sizeof(peerso->last_uuid)); + } socket_unlock(peerso, 1); break; default: @@ -774,7 +811,7 @@ uipc_ctloutput(struct socket *so, struct sockopt *sopt) break; } - return (error); + return error; } /* @@ -786,28 +823,28 @@ uipc_ctloutput(struct socket *so, struct sockopt *sopt) * be large enough for at least one max-size datagram plus address. */ #ifndef PIPSIZ -#define PIPSIZ 8192 +#define PIPSIZ 8192 #endif -static u_int32_t unpst_sendspace = PIPSIZ; -static u_int32_t unpst_recvspace = PIPSIZ; -static u_int32_t unpdg_sendspace = 2*1024; /* really max datagram size */ -static u_int32_t unpdg_recvspace = 4*1024; +static u_int32_t unpst_sendspace = PIPSIZ; +static u_int32_t unpst_recvspace = PIPSIZ; +static u_int32_t unpdg_sendspace = 2 * 1024; /* really max datagram size */ +static u_int32_t unpdg_recvspace = 4 * 1024; -static int unp_rights; /* file descriptors in flight */ -static int unp_disposed; /* discarded file descriptors */ +static int unp_rights; /* file descriptors in flight */ +static int unp_disposed; /* discarded file descriptors */ SYSCTL_DECL(_net_local_stream); SYSCTL_INT(_net_local_stream, OID_AUTO, sendspace, CTLFLAG_RW | CTLFLAG_LOCKED, - &unpst_sendspace, 0, ""); + &unpst_sendspace, 0, ""); SYSCTL_INT(_net_local_stream, OID_AUTO, recvspace, CTLFLAG_RW | CTLFLAG_LOCKED, - &unpst_recvspace, 0, ""); + &unpst_recvspace, 0, ""); SYSCTL_INT(_net_local_stream, OID_AUTO, tracemdns, CTLFLAG_RW | CTLFLAG_LOCKED, - &unpst_tracemdns, 0, ""); + &unpst_tracemdns, 0, ""); SYSCTL_DECL(_net_local_dgram); SYSCTL_INT(_net_local_dgram, OID_AUTO, maxdgram, CTLFLAG_RW | CTLFLAG_LOCKED, - &unpdg_sendspace, 0, ""); + &unpdg_sendspace, 0, ""); SYSCTL_INT(_net_local_dgram, OID_AUTO, recvspace, CTLFLAG_RW | CTLFLAG_LOCKED, - &unpdg_recvspace, 0, ""); + &unpdg_recvspace, 0, ""); SYSCTL_DECL(_net_local); SYSCTL_INT(_net_local, OID_AUTO, inflight, CTLFLAG_RD | CTLFLAG_LOCKED, &unp_rights, 0, ""); @@ -824,7 +861,6 @@ unp_attach(struct socket *so) if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { switch (so->so_type) { - case SOCK_STREAM: error = soreserve(so, unpst_sendspace, unpst_recvspace); break; @@ -836,16 +872,18 @@ unp_attach(struct socket *so) default: panic("unp_attach"); } - if (error) - return (error); + if (error) { + return error; + } } unp = (struct unpcb *)zalloc(unp_zone); - if (unp == NULL) - return (ENOBUFS); - bzero(unp, sizeof (*unp)); + if (unp == NULL) { + return ENOBUFS; + } + bzero(unp, sizeof(*unp)); lck_mtx_init(&unp->unp_mtx, - unp_mtx_grp, unp_mtx_attr); + unp_mtx_grp, unp_mtx_attr); lck_rw_lock_exclusive(unp_list_mtx); LIST_INIT(&unp->unp_refs); @@ -876,7 +914,7 @@ unp_attach(struct socket *so) */ so->so_rcv.sb_flags |= SB_UNIX; so->so_snd.sb_flags |= SB_UNIX; - return (0); + return 0; } static void @@ -905,11 +943,13 @@ unp_detach(struct unpcb *unp) unp->unp_vnode = NULL; } lck_mtx_unlock(unp_connect_lock); - if (tvp != NULL) - vnode_rele(tvp); /* drop the usecount */ + if (tvp != NULL) { + vnode_rele(tvp); /* drop the usecount */ + } } - if (unp->unp_conn) + if (unp->unp_conn) { unp_disconnect(unp); + } while (unp->unp_refs.lh_first) { struct unpcb *unp2 = NULL; @@ -925,15 +965,15 @@ unp_detach(struct unpcb *unp) lck_mtx_lock(unp_disconnect_lock); while (disconnect_in_progress != 0) { (void)msleep((caddr_t)&disconnect_in_progress, unp_disconnect_lock, - PSOCK, "disconnect", NULL); + PSOCK, "disconnect", NULL); } disconnect_in_progress = 1; lck_mtx_unlock(unp_disconnect_lock); /* Now we are sure that any unpcb socket disconnect is not happening */ if (unp->unp_refs.lh_first != NULL) { - unp2 = unp->unp_refs.lh_first; - socket_lock(unp2->unp_socket, 1); + unp2 = unp->unp_refs.lh_first; + socket_lock(unp2->unp_socket, 1); } lck_mtx_lock(unp_disconnect_lock); @@ -943,8 +983,8 @@ unp_detach(struct unpcb *unp) if (unp2 != NULL) { /* We already locked this socket and have a reference on it */ - unp_drop(unp2, ECONNRESET); - socket_unlock(unp2->unp_socket, 1); + unp_drop(unp2, ECONNRESET); + socket_unlock(unp2->unp_socket, 1); } } @@ -984,29 +1024,33 @@ unp_bind( char buf[SOCK_MAXADDRLEN]; if (nam->sa_family != 0 && nam->sa_family != AF_UNIX) { - return (EAFNOSUPPORT); + return EAFNOSUPPORT; } /* * Check if the socket is already bound to an address */ - if (unp->unp_vnode != NULL) - return (EINVAL); + if (unp->unp_vnode != NULL) { + return EINVAL; + } /* * Check if the socket may have been shut down */ if ((so->so_state & (SS_CANTRCVMORE | SS_CANTSENDMORE)) == - (SS_CANTRCVMORE | SS_CANTSENDMORE)) - return (EINVAL); + (SS_CANTRCVMORE | SS_CANTSENDMORE)) { + return EINVAL; + } namelen = soun->sun_len - offsetof(struct sockaddr_un, sun_path); - if (namelen <= 0) - return (EINVAL); + if (namelen <= 0) { + return EINVAL; + } /* * Note: sun_path is not a zero terminated "C" string */ - if (namelen >= SOCK_MAXADDRLEN) - return (EINVAL); + if (namelen >= SOCK_MAXADDRLEN) { + return EINVAL; + } bcopy(soun->sun_path, buf, namelen); buf[namelen] = 0; @@ -1018,7 +1062,7 @@ unp_bind( error = namei(&nd); if (error) { socket_lock(so, 0); - return (error); + return error; } dvp = nd.ni_dvp; vp = nd.ni_vp; @@ -1034,7 +1078,7 @@ unp_bind( vnode_put(vp); socket_lock(so, 0); - return (EADDRINUSE); + return EADDRINUSE; } VATTR_INIT(&va); @@ -1066,16 +1110,28 @@ unp_bind( if (error) { socket_lock(so, 0); - return (error); + return error; } - vnode_ref(vp); /* gain a longterm reference */ + socket_lock(so, 0); + + if (unp->unp_vnode != NULL) { + vnode_put(vp); /* drop the iocount */ + return EINVAL; + } + + error = vnode_ref(vp); /* gain a longterm reference */ + if (error) { + vnode_put(vp); /* drop the iocount */ + return error; + } + vp->v_socket = unp->unp_socket; unp->unp_vnode = vp; unp->unp_addr = (struct sockaddr_un *)dup_sockaddr(nam, 1); - vnode_put(vp); /* drop the iocount */ + vnode_put(vp); /* drop the iocount */ - return (0); + return 0; } @@ -1100,7 +1156,7 @@ unp_connect(struct socket *so, struct sockaddr *nam, __unused proc_t p) { struct sockaddr_un *soun = (struct sockaddr_un *)nam; struct vnode *vp; - struct socket *so2, *so3, *list_so=NULL; + struct socket *so2, *so3, *list_so = NULL; struct unpcb *unp, *unp2, *unp3; vfs_context_t ctx = vfs_context_current(); int error, len; @@ -1108,20 +1164,22 @@ unp_connect(struct socket *so, struct sockaddr *nam, __unused proc_t p) char buf[SOCK_MAXADDRLEN]; if (nam->sa_family != 0 && nam->sa_family != AF_UNIX) { - return (EAFNOSUPPORT); + return EAFNOSUPPORT; } unp = sotounpcb(so); so2 = so3 = NULL; len = nam->sa_len - offsetof(struct sockaddr_un, sun_path); - if (len <= 0) - return (EINVAL); + if (len <= 0) { + return EINVAL; + } /* * Note: sun_path is not a zero terminated "C" string */ - if (len >= SOCK_MAXADDRLEN) - return (EINVAL); + if (len >= SOCK_MAXADDRLEN) { + return EINVAL; + } bcopy(soun->sun_path, buf, len); buf[len] = 0; @@ -1132,7 +1190,7 @@ unp_connect(struct socket *so, struct sockaddr *nam, __unused proc_t p) error = namei(&nd); if (error) { socket_lock(so, 0); - return (error); + return error; } nameidone(&nd); vp = nd.ni_vp; @@ -1227,9 +1285,10 @@ unp_connect(struct socket *so, struct sockaddr *nam, __unused proc_t p) } unp2 = sotounpcb(so2); unp3 = sotounpcb(so3); - if (unp2->unp_addr) + if (unp2->unp_addr) { unp3->unp_addr = (struct sockaddr_un *) dup_sockaddr((struct sockaddr *)unp2->unp_addr, 1); + } /* * unp_peercred management: @@ -1267,10 +1326,10 @@ unp_connect(struct socket *so, struct sockaddr *nam, __unused proc_t p) socket_unlock(so2, 1); socket_lock(so3, 0); sofreelastref(so3, 1); - goto out; + goto out; } memcpy(&unp->unp_peercred, &unp2->unp_peercred, - sizeof (unp->unp_peercred)); + sizeof(unp->unp_peercred)); unp->unp_flags |= UNP_HAVEPC; #if CONFIG_MACF_SOCKET @@ -1295,7 +1354,7 @@ unp_connect(struct socket *so, struct sockaddr *nam, __unused proc_t p) */ if (unpst_tracemdns && !strncmp(soun->sun_path, MDNSRESPONDER_PATH, - sizeof (MDNSRESPONDER_PATH))) { + sizeof(MDNSRESPONDER_PATH))) { unp->unp_flags |= UNP_TRACE_MDNS; unp2->unp_flags |= UNP_TRACE_MDNS; } @@ -1325,7 +1384,7 @@ decref_out: out: LCK_MTX_ASSERT(&unp->unp_mtx, LCK_MTX_ASSERT_OWNED); vnode_put(vp); - return (error); + return error; } /* @@ -1339,8 +1398,9 @@ unp_connect2(struct socket *so, struct socket *so2) struct unpcb *unp = sotounpcb(so); struct unpcb *unp2; - if (so2->so_type != so->so_type) - return (EPROTOTYPE); + if (so2->so_type != so->so_type) { + return EPROTOTYPE; + } unp2 = sotounpcb(so2); @@ -1348,20 +1408,20 @@ unp_connect2(struct socket *so, struct socket *so2) LCK_MTX_ASSERT(&unp2->unp_mtx, LCK_MTX_ASSERT_OWNED); /* Verify both sockets are still opened */ - if (unp == 0 || unp2 == 0) - return (EINVAL); + if (unp == 0 || unp2 == 0) { + return EINVAL; + } unp->unp_conn = unp2; so2->so_usecount++; switch (so->so_type) { - case SOCK_DGRAM: LIST_INSERT_HEAD(&unp2->unp_refs, unp, unp_reflink); if (so != so2) { /* Avoid lock order reversals due to drop/acquire in soisconnected. */ - /* Keep an extra reference on so2 that will be dropped + /* Keep an extra reference on so2 that will be dropped * soon after getting the locks in order */ socket_unlock(so2, 0); @@ -1411,7 +1471,7 @@ unp_connect2(struct socket *so, struct socket *so2) } LCK_MTX_ASSERT(&unp->unp_mtx, LCK_MTX_ASSERT_OWNED); LCK_MTX_ASSERT(&unp2->unp_mtx, LCK_MTX_ASSERT_OWNED); - return (0); + return 0; } static void @@ -1433,7 +1493,7 @@ unp_disconnect(struct unpcb *unp) so_locked = 0; } (void)msleep((caddr_t)&disconnect_in_progress, unp_disconnect_lock, - PSOCK, "disconnect", NULL); + PSOCK, "disconnect", NULL); } disconnect_in_progress = 1; lck_mtx_unlock(unp_disconnect_lock); @@ -1486,7 +1546,7 @@ try_again: so_locked = 0; (void)msleep(waitso->so_pcb, &unp->unp_mtx, - PSOCK | PDROP, "unpdisconnect", NULL); + PSOCK | PDROP, "unpdisconnect", NULL); goto try_again; } @@ -1498,16 +1558,17 @@ try_again: VERIFY(so2->so_usecount > 0); so2->so_usecount--; - if (unp->unp_flags & UNP_TRACE_MDNS) + if (unp->unp_flags & UNP_TRACE_MDNS) { unp->unp_flags &= ~UNP_TRACE_MDNS; + } switch (unp->unp_socket->so_type) { - case SOCK_DGRAM: LIST_REMOVE(unp, unp_reflink); unp->unp_socket->so_state &= ~SS_ISCONNECTED; - if (so != so2) + if (so != so2) { socket_unlock(so2, 1); + } break; case SOCK_STREAM: @@ -1519,14 +1580,15 @@ try_again: * we release all locks except the socket lock, this will avoid * a deadlock. */ - unp->unp_socket->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); - unp->unp_socket->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED); + unp->unp_socket->so_state &= ~(SS_ISCONNECTING | SS_ISCONNECTED | SS_ISDISCONNECTING); + unp->unp_socket->so_state |= (SS_CANTRCVMORE | SS_CANTSENDMORE | SS_ISDISCONNECTED); - unp2->unp_socket->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); - unp->unp_socket->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED); + unp2->unp_socket->so_state &= ~(SS_ISCONNECTING | SS_ISCONNECTED | SS_ISDISCONNECTING); + unp->unp_socket->so_state |= (SS_CANTRCVMORE | SS_CANTSENDMORE | SS_ISDISCONNECTED); - if (unp2->unp_flags & UNP_TRACE_MDNS) + if (unp2->unp_flags & UNP_TRACE_MDNS) { unp2->unp_flags &= ~UNP_TRACE_MDNS; + } strdisconn = 1; break; @@ -1544,7 +1606,7 @@ out: soisdisconnected(so2); socket_unlock(so2, 1); - socket_lock(so,0); + socket_lock(so, 0); soisdisconnected(so); } LCK_MTX_ASSERT(&unp->unp_mtx, LCK_MTX_ASSERT_OWNED); @@ -1614,15 +1676,15 @@ unp_pcblist SYSCTL_HANDLER_ARGS */ if (req->oldptr == USER_ADDR_NULL) { n = unp_count; - req->oldidx = 2 * sizeof (xug) + (n + n / 8) * - sizeof (struct xunpcb); + req->oldidx = 2 * sizeof(xug) + (n + n / 8) * + sizeof(struct xunpcb); lck_rw_done(unp_list_mtx); - return (0); + return 0; } if (req->newptr != USER_ADDR_NULL) { lck_rw_done(unp_list_mtx); - return (EPERM); + return EPERM; } /* @@ -1631,38 +1693,39 @@ unp_pcblist SYSCTL_HANDLER_ARGS gencnt = unp_gencnt; n = unp_count; - bzero(&xug, sizeof (xug)); - xug.xug_len = sizeof (xug); + bzero(&xug, sizeof(xug)); + xug.xug_len = sizeof(xug); xug.xug_count = n; xug.xug_gen = gencnt; xug.xug_sogen = so_gencnt; - error = SYSCTL_OUT(req, &xug, sizeof (xug)); + error = SYSCTL_OUT(req, &xug, sizeof(xug)); if (error) { lck_rw_done(unp_list_mtx); - return (error); + return error; } /* * We are done if there is no pcb */ - if (n == 0) { + if (n == 0) { lck_rw_done(unp_list_mtx); - return (0); + return 0; } - MALLOC(unp_list, struct unpcb **, n * sizeof (*unp_list), + MALLOC(unp_list, struct unpcb **, n * sizeof(*unp_list), M_TEMP, M_WAITOK); if (unp_list == 0) { lck_rw_done(unp_list_mtx); - return (ENOMEM); + return ENOMEM; } for (unp = head->lh_first, i = 0; unp && i < n; unp = unp->unp_link.le_next) { - if (unp->unp_gencnt <= gencnt) + if (unp->unp_gencnt <= gencnt) { unp_list[i++] = unp; + } } - n = i; /* in case we lost some during malloc */ + n = i; /* in case we lost some during malloc */ error = 0; for (i = 0; i < n; i++) { @@ -1670,24 +1733,26 @@ unp_pcblist SYSCTL_HANDLER_ARGS if (unp->unp_gencnt <= gencnt) { struct xunpcb xu; - bzero(&xu, sizeof (xu)); - xu.xu_len = sizeof (xu); + bzero(&xu, sizeof(xu)); + xu.xu_len = sizeof(xu); xu.xu_unpp = (_UNPCB_PTR(struct unpcb_compat *)) VM_KERNEL_ADDRPERM(unp); /* * XXX - need more locking here to protect against * connect/disconnect races for SMP. */ - if (unp->unp_addr) - bcopy(unp->unp_addr, &xu.xu_addr, + if (unp->unp_addr) { + bcopy(unp->unp_addr, &xu.xu_au, unp->unp_addr->sun_len); - if (unp->unp_conn && unp->unp_conn->unp_addr) + } + if (unp->unp_conn && unp->unp_conn->unp_addr) { bcopy(unp->unp_conn->unp_addr, - &xu.xu_caddr, + &xu.xu_cau, unp->unp_conn->unp_addr->sun_len); + } unpcb_to_compat(unp, &xu.xu_unp); sotoxsocket(unp->unp_socket, &xu.xu_socket); - error = SYSCTL_OUT(req, &xu, sizeof (xu)); + error = SYSCTL_OUT(req, &xu, sizeof(xu)); } } if (!error) { @@ -1698,26 +1763,26 @@ unp_pcblist SYSCTL_HANDLER_ARGS * while we were processing this request, and it * might be necessary to retry. */ - bzero(&xug, sizeof (xug)); - xug.xug_len = sizeof (xug); + bzero(&xug, sizeof(xug)); + xug.xug_len = sizeof(xug); xug.xug_gen = unp_gencnt; xug.xug_sogen = so_gencnt; xug.xug_count = unp_count; - error = SYSCTL_OUT(req, &xug, sizeof (xug)); + error = SYSCTL_OUT(req, &xug, sizeof(xug)); } FREE(unp_list, M_TEMP); lck_rw_done(unp_list_mtx); - return (error); + return error; } SYSCTL_PROC(_net_local_dgram, OID_AUTO, pcblist, - CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, - (caddr_t)(long)SOCK_DGRAM, 0, unp_pcblist, "S,xunpcb", - "List of active local datagram sockets"); + CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, + (caddr_t)(long)SOCK_DGRAM, 0, unp_pcblist, "S,xunpcb", + "List of active local datagram sockets"); SYSCTL_PROC(_net_local_stream, OID_AUTO, pcblist, - CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, - (caddr_t)(long)SOCK_STREAM, 0, unp_pcblist, "S,xunpcb", - "List of active local stream sockets"); + CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, + (caddr_t)(long)SOCK_STREAM, 0, unp_pcblist, "S,xunpcb", + "List of active local stream sockets"); #if !CONFIG_EMBEDDED @@ -1740,15 +1805,15 @@ unp_pcblist64 SYSCTL_HANDLER_ARGS */ if (req->oldptr == USER_ADDR_NULL) { n = unp_count; - req->oldidx = 2 * sizeof (xug) + (n + n / 8) * - (sizeof (struct xunpcb64)); + req->oldidx = 2 * sizeof(xug) + (n + n / 8) * + (sizeof(struct xunpcb64)); lck_rw_done(unp_list_mtx); - return (0); + return 0; } if (req->newptr != USER_ADDR_NULL) { lck_rw_done(unp_list_mtx); - return (EPERM); + return EPERM; } /* @@ -1757,45 +1822,46 @@ unp_pcblist64 SYSCTL_HANDLER_ARGS gencnt = unp_gencnt; n = unp_count; - bzero(&xug, sizeof (xug)); - xug.xug_len = sizeof (xug); + bzero(&xug, sizeof(xug)); + xug.xug_len = sizeof(xug); xug.xug_count = n; xug.xug_gen = gencnt; xug.xug_sogen = so_gencnt; - error = SYSCTL_OUT(req, &xug, sizeof (xug)); + error = SYSCTL_OUT(req, &xug, sizeof(xug)); if (error) { lck_rw_done(unp_list_mtx); - return (error); + return error; } /* * We are done if there is no pcb */ - if (n == 0) { + if (n == 0) { lck_rw_done(unp_list_mtx); - return (0); + return 0; } - MALLOC(unp_list, struct unpcb **, n * sizeof (*unp_list), + MALLOC(unp_list, struct unpcb **, n * sizeof(*unp_list), M_TEMP, M_WAITOK); if (unp_list == 0) { lck_rw_done(unp_list_mtx); - return (ENOMEM); + return ENOMEM; } for (unp = head->lh_first, i = 0; unp && i < n; unp = unp->unp_link.le_next) { - if (unp->unp_gencnt <= gencnt) + if (unp->unp_gencnt <= gencnt) { unp_list[i++] = unp; + } } - n = i; /* in case we lost some during malloc */ + n = i; /* in case we lost some during malloc */ error = 0; for (i = 0; i < n; i++) { unp = unp_list[i]; if (unp->unp_gencnt <= gencnt) { struct xunpcb64 xu; - size_t xu_len = sizeof(struct xunpcb64); + size_t xu_len = sizeof(struct xunpcb64); bzero(&xu, xu_len); xu.xu_len = xu_len; @@ -1821,20 +1887,23 @@ unp_pcblist64 SYSCTL_HANDLER_ARGS xu.xunp_mbcnt = unp->unp_mbcnt; xu.xunp_gencnt = unp->unp_gencnt; - if (unp->unp_socket) + if (unp->unp_socket) { sotoxsocket64(unp->unp_socket, &xu.xu_socket); + } /* * XXX - need more locking here to protect against * connect/disconnect races for SMP. */ - if (unp->unp_addr) - bcopy(unp->unp_addr, &xu.xunp_addr, - unp->unp_addr->sun_len); - if (unp->unp_conn && unp->unp_conn->unp_addr) - bcopy(unp->unp_conn->unp_addr, - &xu.xunp_caddr, - unp->unp_conn->unp_addr->sun_len); + if (unp->unp_addr) { + bcopy(unp->unp_addr, &xu.xu_au, + unp->unp_addr->sun_len); + } + if (unp->unp_conn && unp->unp_conn->unp_addr) { + bcopy(unp->unp_conn->unp_addr, + &xu.xu_cau, + unp->unp_conn->unp_addr->sun_len); + } error = SYSCTL_OUT(req, &xu, xu_len); } @@ -1847,26 +1916,26 @@ unp_pcblist64 SYSCTL_HANDLER_ARGS * while we were processing this request, and it * might be necessary to retry. */ - bzero(&xug, sizeof (xug)); - xug.xug_len = sizeof (xug); + bzero(&xug, sizeof(xug)); + xug.xug_len = sizeof(xug); xug.xug_gen = unp_gencnt; xug.xug_sogen = so_gencnt; xug.xug_count = unp_count; - error = SYSCTL_OUT(req, &xug, sizeof (xug)); + error = SYSCTL_OUT(req, &xug, sizeof(xug)); } FREE(unp_list, M_TEMP); lck_rw_done(unp_list_mtx); - return (error); + return error; } SYSCTL_PROC(_net_local_dgram, OID_AUTO, pcblist64, - CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, - (caddr_t)(long)SOCK_DGRAM, 0, unp_pcblist64, "S,xunpcb64", - "List of active local datagram sockets 64 bit"); + CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, + (caddr_t)(long)SOCK_DGRAM, 0, unp_pcblist64, "S,xunpcb64", + "List of active local datagram sockets 64 bit"); SYSCTL_PROC(_net_local_stream, OID_AUTO, pcblist64, - CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, - (caddr_t)(long)SOCK_STREAM, 0, unp_pcblist64, "S,xunpcb64", - "List of active local stream sockets 64 bit"); + CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, + (caddr_t)(long)SOCK_STREAM, 0, unp_pcblist64, "S,xunpcb64", + "List of active local stream sockets 64 bit"); #endif /* !CONFIG_EMBEDDED */ @@ -1900,18 +1969,18 @@ unp_drop(struct unpcb *unp, int errno) int unp_externalize(struct mbuf *rights) { - proc_t p = current_proc(); /* XXX */ + proc_t p = current_proc(); /* XXX */ int i; struct cmsghdr *cm = mtod(rights, struct cmsghdr *); struct fileglob **rp = (struct fileglob **)(cm + 1); int *fds = (int *)(cm + 1); struct fileproc *fp; struct fileproc **fileproc_l; - int newfds = (cm->cmsg_len - sizeof (*cm)) / sizeof (int); + int newfds = (cm->cmsg_len - sizeof(*cm)) / sizeof(int); int f, error = 0; MALLOC(fileproc_l, struct fileproc **, - newfds * sizeof (struct fileproc *), M_TEMP, M_WAITOK); + newfds * sizeof(struct fileproc *), M_TEMP, M_WAITOK); if (fileproc_l == NULL) { error = ENOMEM; goto discard; @@ -1949,20 +2018,20 @@ unp_externalize(struct mbuf *rights) continue; } #endif - if (fdalloc(p, 0, &f)) + if (fdalloc(p, 0, &f)) { panic("unp_externalize:fdalloc"); + } fp = fileproc_alloc_init(NULL); - if (fp == NULL) + if (fp == NULL) { panic("unp_externalize: MALLOC_ZONE"); - fp->f_iocount = 0; + } fp->f_fglob = rp[i]; if (fg_removeuipc_mark(rp[i])) { - /* * Take an iocount on the fp for completing the * removal from the global msg queue */ - fp->f_iocount++; + os_ref_retain_locked(&fp->f_iocount); fileproc_l[i] = fp; } else { fileproc_l[i] = NULL; @@ -1983,31 +2052,34 @@ unp_externalize(struct mbuf *rights) fp_drop(p, fds[i], fileproc_l[i], 0); fileproc_l[i] = NULL; } - if (fds[i] != 0) + if (fds[i] != 0) { (void) OSAddAtomic(-1, &unp_rights); + } } discard: - if (fileproc_l != NULL) + if (fileproc_l != NULL) { FREE(fileproc_l, M_TEMP); + } if (error) { for (i = 0; i < newfds; i++) { unp_discard(*rp, p); *rp++ = NULL; } } - return (error); + return error; } void unp_init(void) { _CASSERT(UIPC_MAX_CMSG_FD >= (MCLBYTES / sizeof(int))); - unp_zone = zinit(sizeof (struct unpcb), - (nmbclusters * sizeof (struct unpcb)), 4096, "unpzone"); + unp_zone = zinit(sizeof(struct unpcb), + (nmbclusters * sizeof(struct unpcb)), 4096, "unpzone"); - if (unp_zone == 0) + if (unp_zone == 0) { panic("unp_init"); + } LIST_INIT(&unp_dhead); LIST_INIT(&unp_shead); @@ -2021,20 +2093,22 @@ unp_init(void) unp_mtx_attr = lck_attr_alloc_init(); if ((unp_list_mtx = lck_rw_alloc_init(unp_mtx_grp, - unp_mtx_attr)) == NULL) - return; /* pretty much dead if this fails... */ - + unp_mtx_attr)) == NULL) { + return; /* pretty much dead if this fails... */ + } if ((unp_disconnect_lock = lck_mtx_alloc_init(unp_mtx_grp, - unp_mtx_attr)) == NULL) + unp_mtx_attr)) == NULL) { return; + } if ((unp_connect_lock = lck_mtx_alloc_init(unp_mtx_grp, - unp_mtx_attr)) == NULL) + unp_mtx_attr)) == NULL) { return; + } } #ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif /* @@ -2056,9 +2130,9 @@ unp_internalize(struct mbuf *control, proc_t p) /* 64bit: cmsg_len is 'uint32_t', m_len is 'long' */ if (cm->cmsg_type != SCM_RIGHTS || cm->cmsg_level != SOL_SOCKET || (socklen_t)cm->cmsg_len != (socklen_t)control->m_len) { - return (EINVAL); + return EINVAL; } - oldfds = (cm->cmsg_len - sizeof (*cm)) / sizeof (int); + oldfds = (cm->cmsg_len - sizeof(*cm)) / sizeof(int); bzero(fg_ins, sizeof(fg_ins)); proc_fdlock(p); @@ -2068,15 +2142,15 @@ unp_internalize(struct mbuf *control, proc_t p) struct fileproc *tmpfp; if (((error = fdgetf_noref(p, fds[i], &tmpfp)) != 0)) { proc_fdunlock(p); - return (error); + return error; } else if (!file_issendable(p, tmpfp)) { proc_fdunlock(p); - return (EINVAL); + return EINVAL; } else if (FP_ISGUARDED(tmpfp, GUARD_SOCKET_IPC)) { error = fp_guard_exception(p, - fds[i], tmpfp, kGUARD_EXC_SOCKET_IPC); + fds[i], tmpfp, kGUARD_EXC_SOCKET_IPC); proc_fdunlock(p); - return (error); + return error; } } rp = (struct fileglob **)(cm + 1); @@ -2086,8 +2160,9 @@ unp_internalize(struct mbuf *control, proc_t p) */ for (i = (oldfds - 1); i >= 0; i--) { (void) fdgetf_noref(p, fds[i], &fp); - if (fg_insertuipc_mark(fp->f_fglob)) + if (fg_insertuipc_mark(fp->f_fglob)) { fg_ins[i / 8] |= 0x80 >> (i % 8); + } rp[i] = fp->f_fglob; } proc_fdunlock(p); @@ -2100,22 +2175,23 @@ unp_internalize(struct mbuf *control, proc_t p) (void) OSAddAtomic(1, &unp_rights); } - return (0); + return 0; } -static int unp_defer, unp_gcing, unp_gcwait; +static int unp_defer, unp_gcing, unp_gcwait; static thread_t unp_gcthread = NULL; /* always called under uipc_lock */ void unp_gc_wait(void) { - if (unp_gcthread == current_thread()) + if (unp_gcthread == current_thread()) { return; + } while (unp_gcing != 0) { unp_gcwait = 1; - msleep(&unp_gcing, uipc_lock, 0 , "unp_gc_wait", NULL); + msleep(&unp_gcing, uipc_lock, 0, "unp_gc_wait", NULL); } } @@ -2145,7 +2221,7 @@ unp_gc(void) */ for (fg = fmsghead.lh_first; fg != 0; fg = fg->f_msglist.le_next) { lck_mtx_lock(&fg->fg_lock); - fg->fg_flag &= ~(FMARK|FDEFER); + fg->fg_flag &= ~(FMARK | FDEFER); lck_mtx_unlock(&fg->fg_lock); } do { @@ -2202,7 +2278,7 @@ unp_gc(void) continue; } if (so->so_proto->pr_domain != localdomain || - (so->so_proto->pr_flags&PR_RIGHTS) == 0) { + (so->so_proto->pr_flags & PR_RIGHTS) == 0) { lck_mtx_unlock(&fg->fg_lock); continue; } @@ -2276,10 +2352,11 @@ unp_gc(void) * * 91/09/19, bsy@cs.cmu.edu */ - extra_ref = _MALLOC(nfiles * sizeof (struct fileglob *), + extra_ref = _MALLOC(nfiles * sizeof(struct fileglob *), M_FILEGLOB, M_WAITOK); - if (extra_ref == NULL) + if (extra_ref == NULL) { goto bail; + } for (nunref = 0, fg = fmsghead.lh_first, fpp = extra_ref; fg != 0; fg = nextfg) { lck_mtx_lock(&fg->fg_lock); @@ -2324,12 +2401,13 @@ unp_gc(void) socket_unlock(so, 0); } } - for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) + for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) { closef_locked((struct fileproc *)0, *fpp, (proc_t)NULL); + } - FREE((caddr_t)extra_ref, M_FILEGLOB); + FREE(extra_ref, M_FILEGLOB); bail: - lck_mtx_lock(uipc_lock); + lck_mtx_lock(uipc_lock); unp_gcing = 0; unp_gcthread = NULL; @@ -2339,8 +2417,9 @@ bail: } lck_mtx_unlock(uipc_lock); - if (need_gcwakeup != 0) + if (need_gcwakeup != 0) { wakeup(&unp_gcing); + } } void @@ -2361,7 +2440,7 @@ unp_listen(struct unpcb *unp, proc_t p) cru2x(safecred, &unp->unp_peercred); kauth_cred_unref(&safecred); unp->unp_flags |= UNP_HAVEPCCACHED; - return (0); + return 0; } static void @@ -2374,20 +2453,23 @@ unp_scan(struct mbuf *m0, void (*op)(struct fileglob *, void *arg), void *arg) int qfds; while (m0) { - for (m = m0; m; m = m->m_next) + for (m = m0; m; m = m->m_next) { if (m->m_type == MT_CONTROL && - (size_t)m->m_len >= sizeof (*cm)) { + (size_t)m->m_len >= sizeof(*cm)) { cm = mtod(m, struct cmsghdr *); if (cm->cmsg_level != SOL_SOCKET || - cm->cmsg_type != SCM_RIGHTS) + cm->cmsg_type != SCM_RIGHTS) { continue; - qfds = (cm->cmsg_len - sizeof (*cm)) / - sizeof (int); + } + qfds = (cm->cmsg_len - sizeof(*cm)) / + sizeof(int); rp = (struct fileglob **)(cm + 1); - for (i = 0; i < qfds; i++) + for (i = 0; i < qfds; i++) { (*op)(*rp++, arg); - break; /* XXX, but saves time */ + } + break; /* XXX, but saves time */ } + } m0 = m0->m_act; } } @@ -2401,7 +2483,7 @@ unp_mark(struct fileglob *fg, __unused void *arg) lck_mtx_unlock(&fg->fg_lock); return; } - fg->fg_flag |= (FMARK|FDEFER); + fg->fg_flag |= (FMARK | FDEFER); lck_mtx_unlock(&fg->fg_lock); @@ -2411,9 +2493,9 @@ unp_mark(struct fileglob *fg, __unused void *arg) static void unp_discard(struct fileglob *fg, void *p) { - if (p == NULL) - p = current_proc(); /* XXX */ - + if (p == NULL) { + p = current_proc(); /* XXX */ + } (void) OSAddAtomic(1, &unp_disposed); if (fg_removeuipc_mark(fg)) { VERIFY(fg->fg_lflags & FG_RMMSGQ); @@ -2428,62 +2510,70 @@ unp_discard(struct fileglob *fg, void *p) int unp_lock(struct socket *so, int refcount, void * lr) - { - void * lr_saved; - if (lr == 0) - lr_saved = (void *) __builtin_return_address(0); - else lr_saved = lr; - - if (so->so_pcb) { - lck_mtx_lock(&((struct unpcb *)so->so_pcb)->unp_mtx); - } else { - panic("unp_lock: so=%p NO PCB! lr=%p ref=0x%x\n", - so, lr_saved, so->so_usecount); - } - - if (so->so_usecount < 0) - panic("unp_lock: so=%p so_pcb=%p lr=%p ref=0x%x\n", - so, so->so_pcb, lr_saved, so->so_usecount); - - if (refcount) { +{ + void * lr_saved; + if (lr == 0) { + lr_saved = (void *) __builtin_return_address(0); + } else { + lr_saved = lr; + } + + if (so->so_pcb) { + lck_mtx_lock(&((struct unpcb *)so->so_pcb)->unp_mtx); + } else { + panic("unp_lock: so=%p NO PCB! lr=%p ref=0x%x\n", + so, lr_saved, so->so_usecount); + } + + if (so->so_usecount < 0) { + panic("unp_lock: so=%p so_pcb=%p lr=%p ref=0x%x\n", + so, so->so_pcb, lr_saved, so->so_usecount); + } + + if (refcount) { VERIFY(so->so_usecount > 0); so->so_usecount++; } - so->lock_lr[so->next_lock_lr] = lr_saved; - so->next_lock_lr = (so->next_lock_lr+1) % SO_LCKDBG_MAX; - return (0); + so->lock_lr[so->next_lock_lr] = lr_saved; + so->next_lock_lr = (so->next_lock_lr + 1) % SO_LCKDBG_MAX; + return 0; } int unp_unlock(struct socket *so, int refcount, void * lr) { - void * lr_saved; - lck_mtx_t * mutex_held = NULL; + void * lr_saved; + lck_mtx_t * mutex_held = NULL; struct unpcb *unp = sotounpcb(so); - if (lr == 0) - lr_saved = (void *) __builtin_return_address(0); - else lr_saved = lr; - - if (refcount) - so->so_usecount--; - - if (so->so_usecount < 0) - panic("unp_unlock: so=%p usecount=%x\n", so, so->so_usecount); - if (so->so_pcb == NULL) { - panic("unp_unlock: so=%p NO PCB usecount=%x\n", so, so->so_usecount); - } else { - mutex_held = &((struct unpcb *)so->so_pcb)->unp_mtx; - } - LCK_MTX_ASSERT(mutex_held, LCK_MTX_ASSERT_OWNED); - so->unlock_lr[so->next_unlock_lr] = lr_saved; - so->next_unlock_lr = (so->next_unlock_lr+1) % SO_LCKDBG_MAX; - - if (so->so_usecount == 0 && (so->so_flags & SOF_PCBCLEARING)) { + if (lr == 0) { + lr_saved = (void *) __builtin_return_address(0); + } else { + lr_saved = lr; + } + + if (refcount) { + so->so_usecount--; + } + + if (so->so_usecount < 0) { + panic("unp_unlock: so=%p usecount=%x\n", so, so->so_usecount); + } + if (so->so_pcb == NULL) { + panic("unp_unlock: so=%p NO PCB usecount=%x\n", so, so->so_usecount); + } else { + mutex_held = &((struct unpcb *)so->so_pcb)->unp_mtx; + } + LCK_MTX_ASSERT(mutex_held, LCK_MTX_ASSERT_OWNED); + so->unlock_lr[so->next_unlock_lr] = lr_saved; + so->next_unlock_lr = (so->next_unlock_lr + 1) % SO_LCKDBG_MAX; + + if (so->so_usecount == 0 && (so->so_flags & SOF_PCBCLEARING)) { sofreelastref(so, 1); - if (unp->unp_addr) + if (unp->unp_addr) { FREE(unp->unp_addr, M_SONAME); + } lck_mtx_unlock(mutex_held); @@ -2495,21 +2585,22 @@ unp_unlock(struct socket *so, int refcount, void * lr) lck_mtx_unlock(mutex_held); } - return (0); + return 0; } lck_mtx_t * unp_getlock(struct socket *so, __unused int flags) { - struct unpcb *unp = (struct unpcb *)so->so_pcb; + struct unpcb *unp = (struct unpcb *)so->so_pcb; - if (so->so_pcb) { - if (so->so_usecount < 0) - panic("unp_getlock: so=%p usecount=%x\n", so, so->so_usecount); - return(&unp->unp_mtx); - } else { - panic("unp_getlock: so=%p NULL so_pcb\n", so); - return (so->so_proto->pr_domain->dom_mtx); - } + if (so->so_pcb) { + if (so->so_usecount < 0) { + panic("unp_getlock: so=%p usecount=%x\n", so, so->so_usecount); + } + return &unp->unp_mtx; + } else { + panic("unp_getlock: so=%p NULL so_pcb\n", so); + return so->so_proto->pr_domain->dom_mtx; + } }