2  * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * The contents of this file constitute Original Code as defined in and 
   7  * are subject to the Apple Public Source License Version 1.1 (the 
   8  * "License").  You may not use this file except in compliance with the 
   9  * License.  Please obtain a copy of the License at 
  10  * http://www.apple.com/publicsource and read it before using this file. 
  12  * This Original Code and all software distributed under the License are 
  13  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  14  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  15  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  16  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the 
  17  * License for the specific language governing rights and limitations 
  20  * @APPLE_LICENSE_HEADER_END@ 
  23  * Copyright (c) 1982, 1986, 1989, 1991, 1993 
  24  *      The Regents of the University of California.  All rights reserved. 
  26  * Redistribution and use in source and binary forms, with or without 
  27  * modification, are permitted provided that the following conditions 
  29  * 1. Redistributions of source code must retain the above copyright 
  30  *    notice, this list of conditions and the following disclaimer. 
  31  * 2. Redistributions in binary form must reproduce the above copyright 
  32  *    notice, this list of conditions and the following disclaimer in the 
  33  *    documentation and/or other materials provided with the distribution. 
  34  * 3. All advertising materials mentioning features or use of this software 
  35  *    must display the following acknowledgement: 
  36  *      This product includes software developed by the University of 
  37  *      California, Berkeley and its contributors. 
  38  * 4. Neither the name of the University nor the names of its contributors 
  39  *    may be used to endorse or promote products derived from this software 
  40  *    without specific prior written permission. 
  42  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 
  43  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  44  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  45  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 
  46  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  47  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  48  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  49  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  50  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  51  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  54  *      From: @(#)uipc_usrreq.c 8.3 (Berkeley) 1/4/94 
  57 #include <sys/param.h> 
  58 #include <sys/systm.h> 
  59 #include <sys/kernel.h> 
  60 #include <sys/domain.h> 
  61 #include <sys/fcntl.h> 
  62 #include <sys/malloc.h>         /* XXX must be before <sys/file.h> */ 
  63 #include <sys/file_internal.h> 
  64 #include <sys/filedesc.h> 
  67 #include <sys/namei.h> 
  68 #include <sys/proc_internal.h> 
  69 #include <sys/kauth.h> 
  70 #include <sys/protosw.h> 
  71 #include <sys/socket.h> 
  72 #include <sys/socketvar.h> 
  74 #include <sys/sysctl.h> 
  76 #include <sys/unpcb.h> 
  77 #include <sys/vnode_internal.h> 
  78 #include <sys/kdebug.h> 
  80 #include <kern/zalloc.h> 
  81 #include <kern/locks.h> 
  83 #define f_msgcount f_fglob->fg_msgcount 
  84 #define f_cred f_fglob->fg_cred 
  85 #define f_ops f_fglob->fg_ops 
  86 #define f_offset f_fglob->fg_offset 
  87 #define f_data f_fglob->fg_data 
  88 struct  zone 
*unp_zone
; 
  89 static  unp_gen_t unp_gencnt
; 
  90 static  u_int unp_count
; 
  91 static  lck_mtx_t               
*unp_mutex
; 
  93 extern lck_mtx_t 
* uipc_lock
; 
  94 static  struct unp_head unp_shead
, unp_dhead
; 
  97  * Unix communications domain. 
 101  *      rethink name space problems 
 102  *      need a proper out-of-band 
 105 static struct   sockaddr sun_noname 
= { sizeof(sun_noname
), AF_LOCAL
, { 0 } }; 
 106 static ino_t    unp_ino
;                /* prototype for fake inode numbers */ 
 108 static int     unp_attach(struct socket 
*); 
 109 static void    unp_detach(struct unpcb 
*); 
 110 static int     unp_bind(struct unpcb 
*,struct sockaddr 
*, struct proc 
*); 
 111 static int     unp_connect(struct socket 
*,struct sockaddr 
*, struct proc 
*); 
 112 static void    unp_disconnect(struct unpcb 
*); 
 113 static void    unp_shutdown(struct unpcb 
*); 
 114 static void    unp_drop(struct unpcb 
*, int); 
 115 static void    unp_gc(void); 
 116 static void    unp_scan(struct mbuf 
*, void (*)(struct fileglob 
*)); 
 117 static void    unp_mark(struct fileglob 
*); 
 118 static void    unp_discard(struct fileglob 
*); 
 119 static void    unp_discard_fdlocked(struct fileglob 
*, struct proc 
*); 
 120 static int     unp_internalize(struct mbuf 
*, struct proc 
*); 
 121 static int     unp_listen(struct unpcb 
*, struct proc 
*); 
 125 uipc_abort(struct socket 
*so
) 
 127         struct unpcb 
*unp 
= sotounpcb(so
); 
 131         unp_drop(unp
, ECONNABORTED
); 
 138 uipc_accept(struct socket 
*so
, struct sockaddr 
**nam
) 
 140         struct unpcb 
*unp 
= sotounpcb(so
); 
 146          * Pass back name of connected socket, 
 147          * if it was bound and we are still connected 
 148          * (our peer may have closed already!). 
 150         if (unp
->unp_conn 
&& unp
->unp_conn
->unp_addr
) { 
 151                 *nam 
= dup_sockaddr((struct sockaddr 
*)unp
->unp_conn
->unp_addr
, 
 154                 *nam 
= dup_sockaddr((struct sockaddr 
*)&sun_noname
, 1); 
 160 uipc_attach(struct socket 
*so
, __unused 
int proto
, __unused 
struct proc 
*p
) 
 162         struct unpcb 
*unp 
= sotounpcb(so
); 
 166         return unp_attach(so
); 
 170 uipc_bind(struct socket 
*so
, struct sockaddr 
*nam
, struct proc 
*p
) 
 172         struct unpcb 
*unp 
= sotounpcb(so
); 
 177         return unp_bind(unp
, nam
, p
); 
 181 uipc_connect(struct socket 
*so
, struct sockaddr 
*nam
, struct proc 
*p
) 
 183         struct unpcb 
*unp 
= sotounpcb(so
); 
 187         return unp_connect(so
, nam
, p
); 
 191 uipc_connect2(struct socket 
*so1
, struct socket 
*so2
) 
 193         struct unpcb 
*unp 
= sotounpcb(so1
); 
 198         return unp_connect2(so1
, so2
); 
 201 /* control is EOPNOTSUPP */ 
 204 uipc_detach(struct socket 
*so
) 
 206         struct unpcb 
*unp 
= sotounpcb(so
); 
 216 uipc_disconnect(struct socket 
*so
) 
 218         struct unpcb 
*unp 
= sotounpcb(so
); 
 227 uipc_listen(struct socket 
*so
, __unused 
struct proc 
*p
) 
 229         struct unpcb 
*unp 
= sotounpcb(so
); 
 231         if (unp 
== 0 || unp
->unp_vnode 
== 0) 
 233         return unp_listen(unp
, p
); 
 237 uipc_peeraddr(struct socket 
*so
, struct sockaddr 
**nam
) 
 239         struct unpcb 
*unp 
= sotounpcb(so
); 
 243         if (unp
->unp_conn 
&& unp
->unp_conn
->unp_addr
) 
 244                 *nam 
= dup_sockaddr((struct sockaddr 
*)unp
->unp_conn
->unp_addr
, 
 250 uipc_rcvd(struct socket 
*so
, __unused 
int flags
) 
 252         struct unpcb 
*unp 
= sotounpcb(so
); 
 257         switch (so
->so_type
) { 
 259                 panic("uipc_rcvd DGRAM?"); 
 263 #define rcv (&so->so_rcv) 
 264 #define snd (&so2->so_snd) 
 265                 if (unp
->unp_conn 
== 0) 
 267                 so2 
= unp
->unp_conn
->unp_socket
; 
 269                  * Adjust backpressure on sender 
 270                  * and wakeup any waiting to write. 
 272                 snd
->sb_mbmax 
+= unp
->unp_mbcnt 
- rcv
->sb_mbcnt
; 
 273                 unp
->unp_mbcnt 
= rcv
->sb_mbcnt
; 
 274                 snd
->sb_hiwat 
+= unp
->unp_cc 
- rcv
->sb_cc
; 
 275                 unp
->unp_cc 
= rcv
->sb_cc
; 
 282                 panic("uipc_rcvd unknown socktype"); 
 287 /* pru_rcvoob is EOPNOTSUPP */ 
 290 uipc_send(struct socket 
*so
, int flags
, struct mbuf 
*m
, struct sockaddr 
*nam
, 
 291           struct mbuf 
*control
, struct proc 
*p
) 
 294         struct unpcb 
*unp 
= sotounpcb(so
); 
 301         if (flags 
& PRUS_OOB
) { 
 306         if (control 
&& (error 
= unp_internalize(control
, p
))) 
 309         switch (so
->so_type
) { 
 312                 struct sockaddr 
*from
; 
 319                         error 
= unp_connect(so
, nam
, p
); 
 323                         if (unp
->unp_conn 
== 0) { 
 328                 so2 
= unp
->unp_conn
->unp_socket
; 
 330                         from 
= (struct sockaddr 
*)unp
->unp_addr
; 
 333                 if (sbappendaddr(&so2
->so_rcv
, from
, m
, control
, &error
)) { 
 345 #define rcv (&so2->so_rcv) 
 346 #define snd (&so->so_snd) 
 347                 /* Connect if not connected yet. */ 
 349                  * Note: A better implementation would complain 
 350                  * if not equal to the peer's address. 
 352                 if ((so
->so_state 
& SS_ISCONNECTED
) == 0) { 
 354                                 error 
= unp_connect(so
, nam
, p
); 
 363                 if (so
->so_state 
& SS_CANTSENDMORE
) { 
 367                 if (unp
->unp_conn 
== 0) 
 368                         panic("uipc_send connected but no connection?"); 
 369                 so2 
= unp
->unp_conn
->unp_socket
; 
 371                  * Send to paired receive port, and then reduce 
 372                  * send buffer hiwater marks to maintain backpressure. 
 375                 if ((control 
&& sbappendcontrol(rcv
, m
, control
, NULL
)) || 
 380                         rcv
->sb_mbcnt 
- unp
->unp_conn
->unp_mbcnt
; 
 381                 unp
->unp_conn
->unp_mbcnt 
= rcv
->sb_mbcnt
; 
 382                 snd
->sb_hiwat 
-= rcv
->sb_cc 
- unp
->unp_conn
->unp_cc
; 
 383                 unp
->unp_conn
->unp_cc 
= rcv
->sb_cc
; 
 394                 panic("uipc_send unknown socktype"); 
 398          * SEND_EOF is equivalent to a SEND followed by 
 401         if (flags 
& PRUS_EOF
) { 
 406         if (control 
&& error 
!= 0) 
 407                 unp_dispose(control
); 
 418 uipc_sense(struct socket 
*so
, struct stat 
*sb
) 
 420         struct unpcb 
*unp 
= sotounpcb(so
); 
 425         sb
->st_blksize 
= so
->so_snd
.sb_hiwat
; 
 426         if (so
->so_type 
== SOCK_STREAM 
&& unp
->unp_conn 
!= 0) { 
 427                 so2 
= unp
->unp_conn
->unp_socket
; 
 428                 sb
->st_blksize 
+= so2
->so_rcv
.sb_cc
; 
 431         if (unp
->unp_ino 
== 0) 
 432                 unp
->unp_ino 
= unp_ino
++; 
 433         sb
->st_ino 
= unp
->unp_ino
; 
 438 uipc_shutdown(struct socket 
*so
) 
 440         struct unpcb 
*unp 
= sotounpcb(so
); 
 450 uipc_sockaddr(struct socket 
*so
, struct sockaddr 
**nam
) 
 452         struct unpcb 
*unp 
= sotounpcb(so
); 
 457                 *nam 
= dup_sockaddr((struct sockaddr 
*)unp
->unp_addr
, 1); 
 461 struct pr_usrreqs uipc_usrreqs 
= { 
 462         uipc_abort
, uipc_accept
, uipc_attach
, uipc_bind
, uipc_connect
, 
 463         uipc_connect2
, pru_control_notsupp
, uipc_detach
, uipc_disconnect
, 
 464         uipc_listen
, uipc_peeraddr
, uipc_rcvd
, pru_rcvoob_notsupp
, 
 465         uipc_send
, uipc_sense
, uipc_shutdown
, uipc_sockaddr
, 
 466         sosend
, soreceive
, pru_sopoll_notsupp
 
 472         struct sockopt 
*sopt
) 
 474         struct unpcb 
*unp 
= sotounpcb(so
); 
 477         switch (sopt
->sopt_dir
) { 
 479                 switch (sopt
->sopt_name
) { 
 481                         if (unp
->unp_flags 
& UNP_HAVEPC
) 
 482                                 error 
= sooptcopyout(sopt
, &unp
->unp_peercred
, 
 483                                     sizeof(unp
->unp_peercred
)); 
 485                                 if (so
->so_type 
== SOCK_STREAM
) 
 505  * Both send and receive buffers are allocated PIPSIZ bytes of buffering 
 506  * for stream sockets, although the total for sender and receiver is 
 507  * actually only PIPSIZ. 
 508  * Datagram sockets really use the sendspace as the maximum datagram size, 
 509  * and don't really want to reserve the sendspace.  Their recvspace should 
 510  * be large enough for at least one max-size datagram plus address. 
 515 static u_long   unpst_sendspace 
= PIPSIZ
; 
 516 static u_long   unpst_recvspace 
= PIPSIZ
; 
 517 static u_long   unpdg_sendspace 
= 2*1024;       /* really max datagram size */ 
 518 static u_long   unpdg_recvspace 
= 4*1024; 
 520 static int      unp_rights
;                     /* file descriptors in flight */ 
 522 SYSCTL_DECL(_net_local_stream
); 
 523 SYSCTL_INT(_net_local_stream
, OID_AUTO
, sendspace
, CTLFLAG_RW
,  
 524            &unpst_sendspace
, 0, ""); 
 525 SYSCTL_INT(_net_local_stream
, OID_AUTO
, recvspace
, CTLFLAG_RW
, 
 526            &unpst_recvspace
, 0, ""); 
 527 SYSCTL_DECL(_net_local_dgram
); 
 528 SYSCTL_INT(_net_local_dgram
, OID_AUTO
, maxdgram
, CTLFLAG_RW
, 
 529            &unpdg_sendspace
, 0, ""); 
 530 SYSCTL_INT(_net_local_dgram
, OID_AUTO
, recvspace
, CTLFLAG_RW
, 
 531            &unpdg_recvspace
, 0, ""); 
 532 SYSCTL_DECL(_net_local
); 
 533 SYSCTL_INT(_net_local
, OID_AUTO
, inflight
, CTLFLAG_RD
, &unp_rights
, 0, ""); 
 536 unp_attach(struct socket 
*so
) 
 541         if (so
->so_snd
.sb_hiwat 
== 0 || so
->so_rcv
.sb_hiwat 
== 0) { 
 542                 switch (so
->so_type
) { 
 545                         error 
= soreserve(so
, unpst_sendspace
, unpst_recvspace
); 
 549                         error 
= soreserve(so
, unpdg_sendspace
, unpdg_recvspace
); 
 558         unp 
= (struct unpcb
*)zalloc(unp_zone
); 
 561         bzero(unp
, sizeof *unp
); 
 562         lck_mtx_lock(unp_mutex
); 
 563         LIST_INIT(&unp
->unp_refs
); 
 564         unp
->unp_socket 
= so
; 
 565         unp
->unp_gencnt 
= ++unp_gencnt
; 
 567         LIST_INSERT_HEAD(so
->so_type 
== SOCK_DGRAM 
? &unp_dhead
 
 568                          : &unp_shead
, unp
, unp_link
); 
 569         so
->so_pcb 
= (caddr_t
)unp
; 
 570         lck_mtx_unlock(unp_mutex
); 
 575 unp_detach(struct unpcb 
*unp
) 
 577         lck_mtx_assert(unp_mutex
, LCK_MTX_ASSERT_OWNED
); 
 578         LIST_REMOVE(unp
, unp_link
); 
 579         unp
->unp_gencnt 
= ++unp_gencnt
; 
 581         if (unp
->unp_vnode
) { 
 582                 struct vnode 
*tvp 
= unp
->unp_vnode
; 
 583                 unp
->unp_vnode
->v_socket 
= 0; 
 585                 vnode_rele(tvp
);                /* drop the usecount */ 
 589         while (unp
->unp_refs
.lh_first
) 
 590                 unp_drop(unp
->unp_refs
.lh_first
, ECONNRESET
); 
 591         soisdisconnected(unp
->unp_socket
); 
 592         unp
->unp_socket
->so_flags 
|= SOF_PCBCLEARING
; /* makes sure we're getting dealloced */ 
 593         unp
->unp_socket
->so_pcb 
= 0; 
 596                  * Normally the receive buffer is flushed later, 
 597                  * in sofree, but if our receive buffer holds references 
 598                  * to descriptors that are now garbage, we will dispose 
 599                  * of those descriptor references after the garbage collector 
 600                  * gets them (resulting in a "panic: closef: count < 0"). 
 602                 sorflush(unp
->unp_socket
); 
 606                 FREE(unp
->unp_addr
, M_SONAME
); 
 607         zfree(unp_zone
, unp
); 
 613         struct sockaddr 
*nam
, 
 616         struct sockaddr_un 
*soun 
= (struct sockaddr_un 
*)nam
; 
 617         struct vnode 
*vp
, *dvp
; 
 618         struct vnode_attr va
; 
 619         struct vfs_context context
; 
 622         char buf
[SOCK_MAXADDRLEN
]; 
 625         context
.vc_ucred 
= p
->p_ucred
;  /* XXX kauth_cred_get() ??? proxy */ 
 627         if (unp
->unp_vnode 
!= NULL
) 
 629         namelen 
= soun
->sun_len 
- offsetof(struct sockaddr_un
, sun_path
); 
 632         strncpy(buf
, soun
->sun_path
, namelen
); 
 633         buf
[namelen
] = 0;       /* null-terminate the string */ 
 634         NDINIT(&nd
, CREATE
, FOLLOW 
| LOCKPARENT
, UIO_SYSSPACE32
, 
 635             CAST_USER_ADDR_T(buf
), &context
); 
 636 /* SHOULD BE ABLE TO ADOPT EXISTING AND wakeup() ALA FIFO's */ 
 646                  * need to do this before the vnode_put of dvp 
 647                  * since we may have to release an fs_nodelock 
 657         /* authorize before creating */ 
 658         error 
= vnode_authorize(dvp
, NULL
, KAUTH_VNODE_ADD_FILE
, &context
); 
 662                 VATTR_SET(&va
, va_type
, VSOCK
); 
 663                 VATTR_SET(&va
, va_mode
, (ACCESSPERMS 
& ~p
->p_fd
->fd_cmask
)); 
 665                 /* create the socket */ 
 666                 error 
= vn_create(dvp
, &vp
, &nd
.ni_cnd
, &va
, 0, &context
); 
 675         vnode_ref(vp
);  /* gain a longterm reference */ 
 676         vp
->v_socket 
= unp
->unp_socket
; 
 678         unp
->unp_addr 
= (struct sockaddr_un 
*)dup_sockaddr(nam
, 1); 
 679         vnode_put(vp
);          /* drop the iocount */ 
 687         struct sockaddr 
*nam
, 
 690         struct sockaddr_un 
*soun 
= (struct sockaddr_un 
*)nam
; 
 692         struct socket 
*so2
, *so3
; 
 693         struct unpcb 
*unp
, *unp2
, *unp3
; 
 694         struct vfs_context context
; 
 697         char buf
[SOCK_MAXADDRLEN
]; 
 700         context
.vc_ucred 
= p
->p_ucred
;  /* XXX kauth_cred_get() ??? proxy */ 
 703         len 
= nam
->sa_len 
- offsetof(struct sockaddr_un
, sun_path
); 
 706         strncpy(buf
, soun
->sun_path
, len
); 
 709         NDINIT(&nd
, LOOKUP
, FOLLOW 
| LOCKLEAF
, UIO_SYSSPACE32
, CAST_USER_ADDR_T(buf
), &context
); 
 716         if (vp
->v_type 
!= VSOCK
) { 
 721         error 
= vnode_authorize(vp
, NULL
, KAUTH_VNODE_WRITE_DATA
, &context
); 
 726                 error 
= ECONNREFUSED
; 
 730         /* make sure the socket can't go away while we're connecting */ 
 733         if (so
->so_type 
!= so2
->so_type
) { 
 739          * Check if socket was connected while we were trying to 
 740          * acquire the funnel. 
 741          * XXX - probably shouldn't return an error for SOCK_DGRAM 
 743         if ((so
->so_state 
& SS_ISCONNECTED
) != 0) { 
 748         if (so
->so_proto
->pr_flags 
& PR_CONNREQUIRED
) { 
 749                 if ((so2
->so_options 
& SO_ACCEPTCONN
) == 0 || 
 750                     (so3 
= sonewconn(so2
, 0, nam
)) == 0) { 
 751                         error 
= ECONNREFUSED
; 
 755                 unp2 
= sotounpcb(so2
); 
 756                 unp3 
= sotounpcb(so3
); 
 758                         unp3
->unp_addr 
= (struct sockaddr_un 
*) 
 759                                 dup_sockaddr((struct sockaddr 
*) 
 763                  * unp_peercred management: 
 765                  * The connecter's (client's) credentials are copied 
 766                  * from its process structure at the time of connect() 
 769                 cru2x(p
->p_ucred
, &unp3
->unp_peercred
); 
 770                 unp3
->unp_flags 
|= UNP_HAVEPC
; 
 772                  * The receiver's (server's) credentials are copied 
 773                  * from the unp_peercred member of socket on which the 
 774                  * former called listen(); unp_listen() cached that 
 775                  * process's credentials at that time so we can use 
 778                 KASSERT(unp2
->unp_flags 
& UNP_HAVEPCCACHED
, 
 779                     ("unp_connect: listener without cached peercred")); 
 780                 memcpy(&unp
->unp_peercred
, &unp2
->unp_peercred
, 
 781                     sizeof(unp
->unp_peercred
)); 
 782                 unp
->unp_flags 
|= UNP_HAVEPC
; 
 784                 so2
->so_usecount
--; /* drop reference taken on so2 */ 
 786                 so3
->so_usecount
++; /* make sure we keep it around */ 
 788         error 
= unp_connect2(so
, so2
); 
 791                 so2
->so_usecount
--; /* release count on socket */ 
 801         struct unpcb 
*unp 
= sotounpcb(so
); 
 804         if (so2
->so_type 
!= so
->so_type
) 
 806         unp2 
= sotounpcb(so2
); 
 808         /* Verify both sockets are still opened */ 
 809         if (unp 
== 0 || unp2 
== 0) 
 812         unp
->unp_conn 
= unp2
; 
 813         switch (so
->so_type
) { 
 816                 LIST_INSERT_HEAD(&unp2
->unp_refs
, unp
, unp_reflink
); 
 821                 /* This takes care of socketpair */ 
 822                 if (!(unp
->unp_flags 
& UNP_HAVEPC
) && !(unp2
->unp_flags 
& UNP_HAVEPC
)) { 
 823                         cru2x(kauth_cred_get(), &unp
->unp_peercred
); 
 824                         unp
->unp_flags 
|= UNP_HAVEPC
; 
 826                         cru2x(kauth_cred_get(), &unp2
->unp_peercred
); 
 827                         unp2
->unp_flags 
|= UNP_HAVEPC
; 
 829                 unp2
->unp_conn 
= unp
; 
 835                 panic("unp_connect2"); 
 841 unp_disconnect(struct unpcb 
*unp
) 
 843         struct unpcb 
*unp2 
= unp
->unp_conn
; 
 847         lck_mtx_assert(unp_mutex
, LCK_MTX_ASSERT_OWNED
); 
 849         switch (unp
->unp_socket
->so_type
) { 
 852                 LIST_REMOVE(unp
, unp_reflink
); 
 853                 unp
->unp_socket
->so_state 
&= ~SS_ISCONNECTED
; 
 857                 soisdisconnected(unp
->unp_socket
); 
 859                 soisdisconnected(unp2
->unp_socket
); 
 866 unp_abort(struct unpcb 
*unp
) 
 874 unp_pcblist SYSCTL_HANDLER_ARGS
 
 877         struct unpcb 
*unp
, **unp_list
; 
 880         struct unp_head 
*head
; 
 882         lck_mtx_lock(unp_mutex
); 
 883         head 
= ((intptr_t)arg1 
== SOCK_DGRAM 
? &unp_dhead 
: &unp_shead
); 
 886          * The process of preparing the PCB list is too time-consuming and 
 887          * resource-intensive to repeat twice on every request. 
 889         if (req
->oldptr 
== USER_ADDR_NULL
) { 
 891                 req
->oldidx 
= 2 * (sizeof xug
) 
 892                         + (n 
+ n
/8) * sizeof(struct xunpcb
); 
 893                 lck_mtx_unlock(unp_mutex
); 
 897         if (req
->newptr 
!= USER_ADDR_NULL
) { 
 898                 lck_mtx_unlock(unp_mutex
); 
 903          * OK, now we're committed to doing something. 
 908         xug
.xug_len 
= sizeof xug
; 
 910         xug
.xug_gen 
= gencnt
; 
 911         xug
.xug_sogen 
= so_gencnt
; 
 912         error 
= SYSCTL_OUT(req
, &xug
, sizeof xug
); 
 914                 lck_mtx_unlock(unp_mutex
); 
 919          * We are done if there is no pcb 
 922             lck_mtx_unlock(unp_mutex
); 
 926         MALLOC(unp_list
, struct unpcb 
**, n 
* sizeof *unp_list
, M_TEMP
, M_WAITOK
); 
 928                 lck_mtx_unlock(unp_mutex
); 
 932         for (unp 
= head
->lh_first
, i 
= 0; unp 
&& i 
< n
; 
 933              unp 
= unp
->unp_link
.le_next
) { 
 934                 if (unp
->unp_gencnt 
<= gencnt
) 
 937         n 
= i
;                  /* in case we lost some during malloc */ 
 940         for (i 
= 0; i 
< n
; i
++) { 
 942                 if (unp
->unp_gencnt 
<= gencnt
) { 
 944                         xu
.xu_len 
= sizeof xu
; 
 945                         xu
.xu_unpp 
= (struct  unpcb_compat 
*)unp
; 
 947                          * XXX - need more locking here to protect against 
 948                          * connect/disconnect races for SMP. 
 951                                 bcopy(unp
->unp_addr
, &xu
.xu_addr
,  
 952                                       unp
->unp_addr
->sun_len
); 
 953                         if (unp
->unp_conn 
&& unp
->unp_conn
->unp_addr
) 
 954                                 bcopy(unp
->unp_conn
->unp_addr
, 
 956                                       unp
->unp_conn
->unp_addr
->sun_len
); 
 957                         bcopy(unp
, &xu
.xu_unp
, sizeof(xu
.xu_unp
)); 
 958                         sotoxsocket(unp
->unp_socket
, &xu
.xu_socket
); 
 959                         error 
= SYSCTL_OUT(req
, &xu
, sizeof xu
); 
 964                  * Give the user an updated idea of our state. 
 965                  * If the generation differs from what we told 
 966                  * her before, she knows that something happened 
 967                  * while we were processing this request, and it 
 968                  * might be necessary to retry. 
 970                 xug
.xug_gen 
= unp_gencnt
; 
 971                 xug
.xug_sogen 
= so_gencnt
; 
 972                 xug
.xug_count 
= unp_count
; 
 973                 error 
= SYSCTL_OUT(req
, &xug
, sizeof xug
); 
 975         FREE(unp_list
, M_TEMP
); 
 976         lck_mtx_unlock(unp_mutex
); 
 980 SYSCTL_PROC(_net_local_dgram
, OID_AUTO
, pcblist
, CTLFLAG_RD
,  
 981             (caddr_t
)(long)SOCK_DGRAM
, 0, unp_pcblist
, "S,xunpcb", 
 982             "List of active local datagram sockets"); 
 983 SYSCTL_PROC(_net_local_stream
, OID_AUTO
, pcblist
, CTLFLAG_RD
,  
 984             (caddr_t
)(long)SOCK_STREAM
, 0, unp_pcblist
, "S,xunpcb", 
 985             "List of active local stream sockets"); 
 988 unp_shutdown(struct unpcb 
*unp
) 
 992         if (unp
->unp_socket
->so_type 
== SOCK_STREAM 
&& unp
->unp_conn 
&& 
 993             (so 
= unp
->unp_conn
->unp_socket
)) 
1002         struct socket 
*so 
= unp
->unp_socket
; 
1004         so
->so_error 
= errno
; 
1005         unp_disconnect(unp
); 
1017 unp_externalize(struct mbuf 
*rights
) 
1019         struct proc 
*p 
= current_proc();                /* XXX */ 
1021         struct cmsghdr 
*cm 
= mtod(rights
, struct cmsghdr 
*); 
1022         struct fileglob 
**rp 
= (struct fileglob 
**)(cm 
+ 1); 
1023         struct fileproc 
*fp
; 
1024         struct fileglob 
*fg
; 
1025         int newfds 
= (cm
->cmsg_len 
- sizeof(*cm
)) / sizeof (int); 
1031          * if the new FD's will not fit, then we free them all 
1033         if (!fdavail(p
, newfds
)) { 
1034                 for (i 
= 0; i 
< newfds
; i
++) { 
1036                         unp_discard_fdlocked(fg
, p
); 
1044          * now change each pointer to an fd in the global table to  
1045          * an integer that is the index to the local fd table entry 
1046          * that we set up to point to the global one we are transferring. 
1047          * XXX this assumes a pointer and int are the same size...! 
1049         for (i 
= 0; i 
< newfds
; i
++) { 
1050                 if (fdalloc(p
, 0, &f
)) 
1051                         panic("unp_externalize"); 
1053                 MALLOC_ZONE(fp
, struct fileproc 
*, sizeof(struct fileproc
), M_FILEPROC
, M_WAITOK
); 
1054                 bzero(fp
, sizeof(struct fileproc
)); 
1057                 p
->p_fd
->fd_ofiles
[f
] = fp
; 
1059                 *fdflags(p
, f
) &= ~UF_RESERVED
; 
1071         unp_zone 
= zinit(sizeof(struct unpcb
),  
1072                          (nmbclusters 
* sizeof(struct unpcb
)),  
1076         LIST_INIT(&unp_dhead
); 
1077         LIST_INIT(&unp_shead
); 
1079         unp_mutex 
= localdomain
.dom_mtx
; 
1083 #define MIN(a,b) (((a)<(b))?(a):(b)) 
1088         struct mbuf 
*control
, 
1091         struct cmsghdr 
*cm 
= mtod(control
, struct cmsghdr 
*); 
1092         struct fileglob 
**rp
; 
1093         struct fileproc 
*fp
; 
1094         register int i
, error
; 
1096         int fdgetf_noref(proc_t
, struct fileglob 
**, struct fileproc 
**); 
1098         if (cm
->cmsg_type 
!= SCM_RIGHTS 
|| cm
->cmsg_level 
!= SOL_SOCKET 
|| 
1099             cm
->cmsg_len 
!= control
->m_len
) { 
1102         oldfds 
= (cm
->cmsg_len 
- sizeof (*cm
)) / sizeof (int); 
1105         rp 
= (struct fileglob 
**)(cm 
+ 1); 
1107         for (i 
= 0; i 
< oldfds
; i
++) { 
1108              if (error 
= fdgetf_noref(p
, *(int *)rp
++, (struct fileglob 
**)0)) { 
1113         rp 
= (struct fileglob 
**)(cm 
+ 1); 
1115         for (i 
= 0; i 
< oldfds
; i
++) { 
1116                 (void) fdgetf_noref(p
, *(int *)rp
, &fp
); 
1117                 fg_insertuipc(fp
->f_fglob
); 
1118                 *rp
++ = fp
->f_fglob
; 
1126 static int      unp_defer
, unp_gcing
; 
1131         register struct fileglob 
*fg
, *nextfg
; 
1132         register struct socket 
*so
; 
1133         struct fileglob 
**extra_ref
, **fpp
; 
1136         lck_mtx_lock(uipc_lock
); 
1138                 lck_mtx_unlock(uipc_lock
); 
1143         lck_mtx_unlock(uipc_lock
); 
1145          * before going through all this, set all FDs to  
1146          * be NOT defered and NOT externally accessible 
1148         for (fg 
= fmsghead
.lh_first
; fg 
!= 0; fg 
= fg
->f_msglist
.le_next
) { 
1149                 lck_mtx_lock(&fg
->fg_lock
); 
1150                 fg
->fg_flag 
&= ~(FMARK
|FDEFER
); 
1151                 lck_mtx_unlock(&fg
->fg_lock
); 
1154                 for (fg 
= fmsghead
.lh_first
; fg 
!= 0; fg 
= fg
->f_msglist
.le_next
) { 
1155                         lck_mtx_lock(&fg
->fg_lock
); 
1157                          * If the file is not open, skip it 
1159                         if (fg
->fg_count 
== 0) { 
1160                                 lck_mtx_unlock(&fg
->fg_lock
); 
1164                          * If we already marked it as 'defer'  in a 
1165                          * previous pass, then try process it this time 
1168                         if (fg
->fg_flag 
& FDEFER
) { 
1169                                 fg
->fg_flag 
&= ~FDEFER
; 
1173                                  * if it's not defered, then check if it's 
1174                                  * already marked.. if so skip it 
1176                                 if (fg
->fg_flag 
& FMARK
){ 
1177                                         lck_mtx_unlock(&fg
->fg_lock
); 
1181                                  * If all references are from messages 
1182                                  * in transit, then skip it. it's not  
1183                                  * externally accessible. 
1185                                 if (fg
->fg_count 
== fg
->fg_msgcount
) { 
1186                                         lck_mtx_unlock(&fg
->fg_lock
); 
1190                                  * If it got this far then it must be 
1191                                  * externally accessible. 
1193                                 fg
->fg_flag 
|= FMARK
; 
1196                          * either it was defered, or it is externally  
1197                          * accessible and not already marked so. 
1198                          * Now check if it is possibly one of OUR sockets. 
1200                         if (fg
->fg_type 
!= DTYPE_SOCKET 
|| 
1201                             (so 
= (struct socket 
*)fg
->fg_data
) == 0) { 
1202                                 lck_mtx_unlock(&fg
->fg_lock
); 
1205                         if (so
->so_proto
->pr_domain 
!= &localdomain 
|| 
1206                             (so
->so_proto
->pr_flags
&PR_RIGHTS
) == 0) { 
1207                                 lck_mtx_unlock(&fg
->fg_lock
); 
1211                         /* if this code is enabled need to run under network funnel */ 
1212                         if (so
->so_rcv
.sb_flags 
& SB_LOCK
) { 
1214                                  * This is problematical; it's not clear 
1215                                  * we need to wait for the sockbuf to be 
1216                                  * unlocked (on a uniprocessor, at least), 
1217                                  * and it's also not clear what to do 
1218                                  * if sbwait returns an error due to receipt 
1219                                  * of a signal.  If sbwait does return 
1220                                  * an error, we'll go into an infinite 
1221                                  * loop.  Delete all of this for now. 
1223                                 (void) sbwait(&so
->so_rcv
); 
1228                          * So, Ok, it's one of our sockets and it IS externally 
1229                          * accessible (or was defered). Now we look 
1230                          * to see if we hold any file descriptors in its 
1231                          * message buffers. Follow those links and mark them  
1232                          * as accessible too. 
1234                         unp_scan(so
->so_rcv
.sb_mb
, unp_mark
); 
1235                         lck_mtx_unlock(&fg
->fg_lock
); 
1237         } while (unp_defer
); 
1239          * We grab an extra reference to each of the file table entries 
1240          * that are not otherwise accessible and then free the rights 
1241          * that are stored in messages on them. 
1243          * The bug in the orginal code is a little tricky, so I'll describe 
1244          * what's wrong with it here. 
1246          * It is incorrect to simply unp_discard each entry for f_msgcount 
1247          * times -- consider the case of sockets A and B that contain 
1248          * references to each other.  On a last close of some other socket, 
1249          * we trigger a gc since the number of outstanding rights (unp_rights) 
1250          * is non-zero.  If during the sweep phase the gc code un_discards, 
1251          * we end up doing a (full) closef on the descriptor.  A closef on A 
1252          * results in the following chain.  Closef calls soo_close, which 
1253          * calls soclose.   Soclose calls first (through the switch 
1254          * uipc_usrreq) unp_detach, which re-invokes unp_gc.  Unp_gc simply 
1255          * returns because the previous instance had set unp_gcing, and 
1256          * we return all the way back to soclose, which marks the socket 
1257          * with SS_NOFDREF, and then calls sofree.  Sofree calls sorflush 
1258          * to free up the rights that are queued in messages on the socket A, 
1259          * i.e., the reference on B.  The sorflush calls via the dom_dispose 
1260          * switch unp_dispose, which unp_scans with unp_discard.  This second 
1261          * instance of unp_discard just calls closef on B. 
1263          * Well, a similar chain occurs on B, resulting in a sorflush on B, 
1264          * which results in another closef on A.  Unfortunately, A is already 
1265          * being closed, and the descriptor has already been marked with 
1266          * SS_NOFDREF, and soclose panics at this point. 
1268          * Here, we first take an extra reference to each inaccessible 
1269          * descriptor.  Then, we call sorflush ourself, since we know 
1270          * it is a Unix domain socket anyhow.  After we destroy all the 
1271          * rights carried in messages, we do a last closef to get rid 
1272          * of our extra reference.  This is the last close, and the 
1273          * unp_detach etc will shut down the socket. 
1275          * 91/09/19, bsy@cs.cmu.edu 
1277         extra_ref 
= _MALLOC(nfiles 
* sizeof(struct fileglob 
*), M_FILEGLOB
, M_WAITOK
); 
1278         for (nunref 
= 0, fg 
= fmsghead
.lh_first
, fpp 
= extra_ref
; fg 
!= 0; 
1280                 lck_mtx_lock(&fg
->fg_lock
); 
1282                 nextfg 
= fg
->f_msglist
.le_next
; 
1284                  * If it's not open, skip it 
1286                 if (fg
->fg_count 
== 0) { 
1287                         lck_mtx_unlock(&fg
->fg_lock
); 
1291                  * If all refs are from msgs, and it's not marked accessible 
1292                  * then it must be referenced from some unreachable cycle 
1293                  * of (shut-down) FDs, so include it in our 
1294                  * list of FDs to remove 
1296                 if (fg
->fg_count 
== fg
->fg_msgcount 
&& !(fg
->fg_flag 
& FMARK
)) { 
1301                 lck_mtx_unlock(&fg
->fg_lock
); 
1304          * for each FD on our hit list, do the following two things 
1306         for (i 
= nunref
, fpp 
= extra_ref
; --i 
>= 0; ++fpp
) { 
1307                 struct fileglob 
*tfg
; 
1311                 if (tfg
->fg_type 
== DTYPE_SOCKET 
&& tfg
->fg_data 
!= NULL
) { 
1312                         sorflush((struct socket 
*)(tfg
->fg_data
)); 
1315         for (i 
= nunref
, fpp 
= extra_ref
; --i 
>= 0; ++fpp
) 
1316                 closef_locked((struct fileproc 
*)0, *fpp
, (struct proc 
*) NULL
); 
1318         FREE((caddr_t
)extra_ref
, M_FILEGLOB
); 
1323 unp_dispose(struct mbuf 
*m
) 
1327                 unp_scan(m
, unp_discard
); 
1337         cru2x(p
->p_ucred
, &unp
->unp_peercred
); 
1338         unp
->unp_flags 
|= UNP_HAVEPCCACHED
; 
1342 /* should run under kernel funnel */  
1346         void (*op
)(struct fileglob 
*)) 
1349         struct fileglob 
**rp
; 
1355                 for (m 
= m0
; m
; m 
= m
->m_next
) 
1356                         if (m
->m_type 
== MT_CONTROL 
&& 
1357                             (size_t) m
->m_len 
>= sizeof(*cm
)) { 
1358                                 cm 
= mtod(m
, struct cmsghdr 
*); 
1359                                 if (cm
->cmsg_level 
!= SOL_SOCKET 
|| 
1360                                     cm
->cmsg_type 
!= SCM_RIGHTS
) 
1362                                 qfds 
= (cm
->cmsg_len 
- sizeof *cm
) 
1363                                                 / sizeof (struct fileglob 
*); 
1364                                 rp 
= (struct fileglob 
**)(cm 
+ 1); 
1365                                 for (i 
= 0; i 
< qfds
; i
++) 
1367                                 break;          /* XXX, but saves time */ 
1373 /* should run under kernel funnel */ 
1375 unp_mark(struct fileglob 
*fg
) 
1377         lck_mtx_lock(&fg
->fg_lock
); 
1379         if (fg
->fg_flag 
& FMARK
) { 
1380                 lck_mtx_unlock(&fg
->fg_lock
); 
1383         fg
->fg_flag 
|= (FMARK
|FDEFER
); 
1385         lck_mtx_unlock(&fg
->fg_lock
); 
1390 /* should run under kernel funnel */ 
1393         struct fileglob 
*fg
; 
1395         struct proc 
*p 
= current_proc();                /* XXX */ 
1398         unp_discard_fdlocked(fg
, p
); 
1402 unp_discard_fdlocked(fg
, p
) 
1403         struct fileglob 
*fg
; 
1410         (void) closef_locked((struct fileproc 
*)0, fg
, p
);