1 /* 2 * Copyright (c) 1982, 1986, 1989, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * From: @(#)uipc_usrreq.c 8.3 (Berkeley) 1/4/94 34 * $FreeBSD: src/sys/kern/uipc_usrreq.c,v 1.54.2.10 2003/03/04 17:28:09 nectar Exp $ 35 * $DragonFly: src/sys/kern/uipc_usrreq.c,v 1.44 2008/09/06 05:44:58 dillon Exp $ 36 */ 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/kernel.h> 41 #include <sys/domain.h> 42 #include <sys/fcntl.h> 43 #include <sys/malloc.h> /* XXX must be before <sys/file.h> */ 44 #include <sys/proc.h> 45 #include <sys/file.h> 46 #include <sys/filedesc.h> 47 #include <sys/mbuf.h> 48 #include <sys/nlookup.h> 49 #include <sys/protosw.h> 50 #include <sys/socket.h> 51 #include <sys/socketvar.h> 52 #include <sys/resourcevar.h> 53 #include <sys/stat.h> 54 #include <sys/mount.h> 55 #include <sys/sysctl.h> 56 #include <sys/un.h> 57 #include <sys/unpcb.h> 58 #include <sys/vnode.h> 59 60 #include <sys/file2.h> 61 #include <sys/spinlock2.h> 62 #include <sys/socketvar2.h> 63 #include <sys/msgport2.h> 64 65 typedef struct unp_defdiscard { 66 struct unp_defdiscard *next; 67 struct file *fp; 68 } *unp_defdiscard_t; 69 70 static MALLOC_DEFINE(M_UNPCB, "unpcb", "unpcb struct"); 71 static unp_gen_t unp_gencnt; 72 static u_int unp_count; 73 74 static struct unp_head unp_shead, unp_dhead; 75 76 static struct lwkt_token unp_token = LWKT_TOKEN_MP_INITIALIZER(unp_token); 77 static int unp_defdiscard_nest; 78 static unp_defdiscard_t unp_defdiscard_base; 79 80 /* 81 * Unix communications domain. 82 * 83 * TODO: 84 * RDM 85 * rethink name space problems 86 * need a proper out-of-band 87 * lock pushdown 88 */ 89 static struct sockaddr sun_noname = { sizeof(sun_noname), AF_LOCAL }; 90 static ino_t unp_ino = 1; /* prototype for fake inode numbers */ 91 static struct spinlock unp_ino_spin = SPINLOCK_INITIALIZER(&unp_ino_spin); 92 93 static int unp_attach (struct socket *, struct pru_attach_info *); 94 static void unp_detach (struct unpcb *); 95 static int unp_bind (struct unpcb *,struct sockaddr *, struct thread *); 96 static int unp_connect (struct socket *,struct sockaddr *, 97 struct thread *); 98 static void unp_disconnect (struct unpcb *); 99 static void unp_shutdown (struct unpcb *); 100 static void unp_drop (struct unpcb *, int); 101 static void unp_gc (void); 102 static int unp_gc_clearmarks(struct file *, void *); 103 static int unp_gc_checkmarks(struct file *, void *); 104 static int unp_gc_checkrefs(struct file *, void *); 105 static int unp_revoke_gc_check(struct file *, void *); 106 static void unp_scan (struct mbuf *, void (*)(struct file *, void *), 107 void *data); 108 static void unp_mark (struct file *, void *data); 109 static void unp_discard (struct file *, void *); 110 static int unp_internalize (struct mbuf *, struct thread *); 111 static int unp_listen (struct unpcb *, struct thread *); 112 static void unp_fp_externalize(struct lwp *lp, struct file *fp, int fd); 113 114 /* 115 * NOTE: (so) is referenced from soabort*() and netmsg_pru_abort() 116 * will sofree() it when we return. 117 */ 118 static void 119 uipc_abort(netmsg_t msg) 120 { 121 struct unpcb *unp; 122 int error; 123 124 lwkt_gettoken(&unp_token); 125 unp = msg->base.nm_so->so_pcb; 126 if (unp) { 127 unp_drop(unp, ECONNABORTED); 128 unp_detach(unp); 129 error = 0; 130 } else { 131 error = EINVAL; 132 } 133 lwkt_reltoken(&unp_token); 134 135 lwkt_replymsg(&msg->lmsg, error); 136 } 137 138 static void 139 uipc_accept(netmsg_t msg) 140 { 141 struct unpcb *unp; 142 int error; 143 144 lwkt_gettoken(&unp_token); 145 unp = msg->base.nm_so->so_pcb; 146 if (unp == NULL) { 147 error = EINVAL; 148 } else { 149 /* 150 * Pass back name of connected socket, 151 * if it was bound and we are still connected 152 * (our peer may have closed already!). 153 */ 154 if (unp->unp_conn && unp->unp_conn->unp_addr) { 155 *msg->accept.nm_nam = dup_sockaddr( 156 (struct sockaddr *)unp->unp_conn->unp_addr); 157 } else { 158 *msg->accept.nm_nam = dup_sockaddr( 159 (struct sockaddr *)&sun_noname); 160 } 161 error = 0; 162 } 163 lwkt_reltoken(&unp_token); 164 lwkt_replymsg(&msg->lmsg, error); 165 } 166 167 static void 168 uipc_attach(netmsg_t msg) 169 { 170 struct unpcb *unp; 171 int error; 172 173 lwkt_gettoken(&unp_token); 174 unp = msg->base.nm_so->so_pcb; 175 if (unp) 176 error = EISCONN; 177 else 178 error = unp_attach(msg->base.nm_so, msg->attach.nm_ai); 179 lwkt_reltoken(&unp_token); 180 lwkt_replymsg(&msg->lmsg, error); 181 } 182 183 static void 184 uipc_bind(netmsg_t msg) 185 { 186 struct unpcb *unp; 187 int error; 188 189 lwkt_gettoken(&unp_token); 190 unp = msg->base.nm_so->so_pcb; 191 if (unp) 192 error = unp_bind(unp, msg->bind.nm_nam, msg->bind.nm_td); 193 else 194 error = EINVAL; 195 lwkt_reltoken(&unp_token); 196 lwkt_replymsg(&msg->lmsg, error); 197 } 198 199 static void 200 uipc_connect(netmsg_t msg) 201 { 202 struct unpcb *unp; 203 int error; 204 205 lwkt_gettoken(&unp_token); 206 unp = msg->base.nm_so->so_pcb; 207 if (unp) { 208 error = unp_connect(msg->base.nm_so, 209 msg->connect.nm_nam, 210 msg->connect.nm_td); 211 } else { 212 error = EINVAL; 213 } 214 lwkt_reltoken(&unp_token); 215 lwkt_replymsg(&msg->lmsg, error); 216 } 217 218 static void 219 uipc_connect2(netmsg_t msg) 220 { 221 struct unpcb *unp; 222 int error; 223 224 lwkt_gettoken(&unp_token); 225 unp = msg->connect2.nm_so1->so_pcb; 226 if (unp) { 227 error = unp_connect2(msg->connect2.nm_so1, 228 msg->connect2.nm_so2); 229 } else { 230 error = EINVAL; 231 } 232 lwkt_reltoken(&unp_token); 233 lwkt_replymsg(&msg->lmsg, error); 234 } 235 236 /* control is EOPNOTSUPP */ 237 238 static void 239 uipc_detach(netmsg_t msg) 240 { 241 struct unpcb *unp; 242 int error; 243 244 lwkt_gettoken(&unp_token); 245 unp = msg->base.nm_so->so_pcb; 246 if (unp) { 247 unp_detach(unp); 248 error = 0; 249 } else { 250 error = EINVAL; 251 } 252 lwkt_reltoken(&unp_token); 253 lwkt_replymsg(&msg->lmsg, error); 254 } 255 256 static void 257 uipc_disconnect(netmsg_t msg) 258 { 259 struct unpcb *unp; 260 int error; 261 262 lwkt_gettoken(&unp_token); 263 unp = msg->base.nm_so->so_pcb; 264 if (unp) { 265 unp_disconnect(unp); 266 error = 0; 267 } else { 268 error = EINVAL; 269 } 270 lwkt_reltoken(&unp_token); 271 lwkt_replymsg(&msg->lmsg, error); 272 } 273 274 static void 275 uipc_listen(netmsg_t msg) 276 { 277 struct unpcb *unp; 278 int error; 279 280 lwkt_gettoken(&unp_token); 281 unp = msg->base.nm_so->so_pcb; 282 if (unp == NULL || unp->unp_vnode == NULL) 283 error = EINVAL; 284 else 285 error = unp_listen(unp, msg->listen.nm_td); 286 lwkt_reltoken(&unp_token); 287 lwkt_replymsg(&msg->lmsg, error); 288 } 289 290 static void 291 uipc_peeraddr(netmsg_t msg) 292 { 293 struct unpcb *unp; 294 int error; 295 296 lwkt_gettoken(&unp_token); 297 unp = msg->base.nm_so->so_pcb; 298 if (unp == NULL) { 299 error = EINVAL; 300 } else if (unp->unp_conn && unp->unp_conn->unp_addr) { 301 *msg->peeraddr.nm_nam = dup_sockaddr( 302 (struct sockaddr *)unp->unp_conn->unp_addr); 303 error = 0; 304 } else { 305 /* 306 * XXX: It seems that this test always fails even when 307 * connection is established. So, this else clause is 308 * added as workaround to return PF_LOCAL sockaddr. 309 */ 310 *msg->peeraddr.nm_nam = dup_sockaddr( 311 (struct sockaddr *)&sun_noname); 312 error = 0; 313 } 314 lwkt_reltoken(&unp_token); 315 lwkt_replymsg(&msg->lmsg, error); 316 } 317 318 static void 319 uipc_rcvd(netmsg_t msg) 320 { 321 struct unpcb *unp; 322 struct socket *so; 323 struct socket *so2; 324 int error; 325 326 lwkt_gettoken(&unp_token); 327 so = msg->base.nm_so; 328 unp = so->so_pcb; 329 if (unp == NULL) { 330 error = EINVAL; 331 goto done; 332 } 333 334 switch (so->so_type) { 335 case SOCK_DGRAM: 336 panic("uipc_rcvd DGRAM?"); 337 /*NOTREACHED*/ 338 case SOCK_STREAM: 339 case SOCK_SEQPACKET: 340 if (unp->unp_conn == NULL) 341 break; 342 /* 343 * Because we are transfering mbufs directly to the 344 * peer socket we have to use SSB_STOP on the sender 345 * to prevent it from building up infinite mbufs. 346 */ 347 so2 = unp->unp_conn->unp_socket; 348 if (so->so_rcv.ssb_cc < so2->so_snd.ssb_hiwat && 349 so->so_rcv.ssb_mbcnt < so2->so_snd.ssb_mbmax 350 ) { 351 atomic_clear_int(&so2->so_snd.ssb_flags, SSB_STOP); 352 sowwakeup(so2); 353 } 354 break; 355 default: 356 panic("uipc_rcvd unknown socktype"); 357 /*NOTREACHED*/ 358 } 359 error = 0; 360 done: 361 lwkt_reltoken(&unp_token); 362 lwkt_replymsg(&msg->lmsg, error); 363 } 364 365 /* pru_rcvoob is EOPNOTSUPP */ 366 367 static void 368 uipc_send(netmsg_t msg) 369 { 370 struct unpcb *unp; 371 struct socket *so; 372 struct socket *so2; 373 struct mbuf *control; 374 struct mbuf *m; 375 int error = 0; 376 377 lwkt_gettoken(&unp_token); 378 so = msg->base.nm_so; 379 control = msg->send.nm_control; 380 m = msg->send.nm_m; 381 unp = so->so_pcb; 382 383 if (unp == NULL) { 384 error = EINVAL; 385 goto release; 386 } 387 if (msg->send.nm_flags & PRUS_OOB) { 388 error = EOPNOTSUPP; 389 goto release; 390 } 391 392 if (control && (error = unp_internalize(control, msg->send.nm_td))) 393 goto release; 394 395 switch (so->so_type) { 396 case SOCK_DGRAM: 397 { 398 struct sockaddr *from; 399 400 if (msg->send.nm_addr) { 401 if (unp->unp_conn) { 402 error = EISCONN; 403 break; 404 } 405 error = unp_connect(so, 406 msg->send.nm_addr, 407 msg->send.nm_td); 408 if (error) 409 break; 410 } else { 411 if (unp->unp_conn == NULL) { 412 error = ENOTCONN; 413 break; 414 } 415 } 416 so2 = unp->unp_conn->unp_socket; 417 if (unp->unp_addr) 418 from = (struct sockaddr *)unp->unp_addr; 419 else 420 from = &sun_noname; 421 422 lwkt_gettoken(&so2->so_rcv.ssb_token); 423 if (ssb_appendaddr(&so2->so_rcv, from, m, control)) { 424 sorwakeup(so2); 425 m = NULL; 426 control = NULL; 427 } else { 428 error = ENOBUFS; 429 } 430 if (msg->send.nm_addr) 431 unp_disconnect(unp); 432 lwkt_reltoken(&so2->so_rcv.ssb_token); 433 break; 434 } 435 436 case SOCK_STREAM: 437 case SOCK_SEQPACKET: 438 /* Connect if not connected yet. */ 439 /* 440 * Note: A better implementation would complain 441 * if not equal to the peer's address. 442 */ 443 if (!(so->so_state & SS_ISCONNECTED)) { 444 if (msg->send.nm_addr) { 445 error = unp_connect(so, 446 msg->send.nm_addr, 447 msg->send.nm_td); 448 if (error) 449 break; /* XXX */ 450 } else { 451 error = ENOTCONN; 452 break; 453 } 454 } 455 456 if (so->so_state & SS_CANTSENDMORE) { 457 error = EPIPE; 458 break; 459 } 460 if (unp->unp_conn == NULL) 461 panic("uipc_send connected but no connection?"); 462 so2 = unp->unp_conn->unp_socket; 463 /* 464 * Send to paired receive port, and then reduce 465 * send buffer hiwater marks to maintain backpressure. 466 * Wake up readers. 467 */ 468 lwkt_gettoken(&so2->so_rcv.ssb_token); 469 if (control) { 470 if (ssb_appendcontrol(&so2->so_rcv, m, control)) { 471 control = NULL; 472 m = NULL; 473 } 474 } else if (so->so_type == SOCK_SEQPACKET) { 475 sbappendrecord(&so2->so_rcv.sb, m); 476 m = NULL; 477 } else { 478 sbappend(&so2->so_rcv.sb, m); 479 m = NULL; 480 } 481 482 /* 483 * Because we are transfering mbufs directly to the 484 * peer socket we have to use SSB_STOP on the sender 485 * to prevent it from building up infinite mbufs. 486 */ 487 if (so2->so_rcv.ssb_cc >= so->so_snd.ssb_hiwat || 488 so2->so_rcv.ssb_mbcnt >= so->so_snd.ssb_mbmax 489 ) { 490 atomic_set_int(&so->so_snd.ssb_flags, SSB_STOP); 491 } 492 lwkt_reltoken(&so2->so_rcv.ssb_token); 493 sorwakeup(so2); 494 break; 495 496 default: 497 panic("uipc_send unknown socktype"); 498 } 499 500 /* 501 * SEND_EOF is equivalent to a SEND followed by a SHUTDOWN. 502 */ 503 if (msg->send.nm_flags & PRUS_EOF) { 504 socantsendmore(so); 505 unp_shutdown(unp); 506 } 507 508 if (control && error != 0) 509 unp_dispose(control); 510 511 release: 512 lwkt_reltoken(&unp_token); 513 514 if (control) 515 m_freem(control); 516 if (m) 517 m_freem(m); 518 lwkt_replymsg(&msg->lmsg, error); 519 } 520 521 /* 522 * MPSAFE 523 */ 524 static void 525 uipc_sense(netmsg_t msg) 526 { 527 struct unpcb *unp; 528 struct socket *so; 529 struct stat *sb; 530 int error; 531 532 lwkt_gettoken(&unp_token); 533 so = msg->base.nm_so; 534 sb = msg->sense.nm_stat; 535 unp = so->so_pcb; 536 if (unp == NULL) { 537 error = EINVAL; 538 goto done; 539 } 540 sb->st_blksize = so->so_snd.ssb_hiwat; 541 sb->st_dev = NOUDEV; 542 if (unp->unp_ino == 0) { /* make up a non-zero inode number */ 543 spin_lock(&unp_ino_spin); 544 unp->unp_ino = unp_ino++; 545 spin_unlock(&unp_ino_spin); 546 } 547 sb->st_ino = unp->unp_ino; 548 error = 0; 549 done: 550 lwkt_reltoken(&unp_token); 551 lwkt_replymsg(&msg->lmsg, error); 552 } 553 554 static void 555 uipc_shutdown(netmsg_t msg) 556 { 557 struct socket *so; 558 struct unpcb *unp; 559 int error; 560 561 lwkt_gettoken(&unp_token); 562 so = msg->base.nm_so; 563 unp = so->so_pcb; 564 if (unp) { 565 socantsendmore(so); 566 unp_shutdown(unp); 567 error = 0; 568 } else { 569 error = EINVAL; 570 } 571 lwkt_reltoken(&unp_token); 572 lwkt_replymsg(&msg->lmsg, error); 573 } 574 575 static void 576 uipc_sockaddr(netmsg_t msg) 577 { 578 struct unpcb *unp; 579 int error; 580 581 lwkt_gettoken(&unp_token); 582 unp = msg->base.nm_so->so_pcb; 583 if (unp) { 584 if (unp->unp_addr) { 585 *msg->sockaddr.nm_nam = 586 dup_sockaddr((struct sockaddr *)unp->unp_addr); 587 } 588 error = 0; 589 } else { 590 error = EINVAL; 591 } 592 lwkt_reltoken(&unp_token); 593 lwkt_replymsg(&msg->lmsg, error); 594 } 595 596 struct pr_usrreqs uipc_usrreqs = { 597 .pru_abort = uipc_abort, 598 .pru_accept = uipc_accept, 599 .pru_attach = uipc_attach, 600 .pru_bind = uipc_bind, 601 .pru_connect = uipc_connect, 602 .pru_connect2 = uipc_connect2, 603 .pru_control = pr_generic_notsupp, 604 .pru_detach = uipc_detach, 605 .pru_disconnect = uipc_disconnect, 606 .pru_listen = uipc_listen, 607 .pru_peeraddr = uipc_peeraddr, 608 .pru_rcvd = uipc_rcvd, 609 .pru_rcvoob = pr_generic_notsupp, 610 .pru_send = uipc_send, 611 .pru_sense = uipc_sense, 612 .pru_shutdown = uipc_shutdown, 613 .pru_sockaddr = uipc_sockaddr, 614 .pru_sosend = sosend, 615 .pru_soreceive = soreceive 616 }; 617 618 void 619 uipc_ctloutput(netmsg_t msg) 620 { 621 struct socket *so; 622 struct sockopt *sopt; 623 struct unpcb *unp; 624 int error = 0; 625 626 lwkt_gettoken(&unp_token); 627 so = msg->base.nm_so; 628 sopt = msg->ctloutput.nm_sopt; 629 unp = so->so_pcb; 630 631 switch (sopt->sopt_dir) { 632 case SOPT_GET: 633 switch (sopt->sopt_name) { 634 case LOCAL_PEERCRED: 635 if (unp->unp_flags & UNP_HAVEPC) 636 soopt_from_kbuf(sopt, &unp->unp_peercred, 637 sizeof(unp->unp_peercred)); 638 else { 639 if (so->so_type == SOCK_STREAM) 640 error = ENOTCONN; 641 else if (so->so_type == SOCK_SEQPACKET) 642 error = ENOTCONN; 643 else 644 error = EINVAL; 645 } 646 break; 647 default: 648 error = EOPNOTSUPP; 649 break; 650 } 651 break; 652 case SOPT_SET: 653 default: 654 error = EOPNOTSUPP; 655 break; 656 } 657 lwkt_reltoken(&unp_token); 658 lwkt_replymsg(&msg->lmsg, error); 659 } 660 661 /* 662 * Both send and receive buffers are allocated PIPSIZ bytes of buffering 663 * for stream sockets, although the total for sender and receiver is 664 * actually only PIPSIZ. 665 * 666 * Datagram sockets really use the sendspace as the maximum datagram size, 667 * and don't really want to reserve the sendspace. Their recvspace should 668 * be large enough for at least one max-size datagram plus address. 669 * 670 * We want the local send/recv space to be significant larger then lo0's 671 * mtu of 16384. 672 */ 673 #ifndef PIPSIZ 674 #define PIPSIZ 57344 675 #endif 676 static u_long unpst_sendspace = PIPSIZ; 677 static u_long unpst_recvspace = PIPSIZ; 678 static u_long unpdg_sendspace = 2*1024; /* really max datagram size */ 679 static u_long unpdg_recvspace = 4*1024; 680 681 static int unp_rights; /* file descriptors in flight */ 682 static struct spinlock unp_spin = SPINLOCK_INITIALIZER(&unp_spin); 683 684 SYSCTL_DECL(_net_local_seqpacket); 685 SYSCTL_DECL(_net_local_stream); 686 SYSCTL_INT(_net_local_stream, OID_AUTO, sendspace, CTLFLAG_RW, 687 &unpst_sendspace, 0, "Size of stream socket send buffer"); 688 SYSCTL_INT(_net_local_stream, OID_AUTO, recvspace, CTLFLAG_RW, 689 &unpst_recvspace, 0, "Size of stream socket receive buffer"); 690 691 SYSCTL_DECL(_net_local_dgram); 692 SYSCTL_INT(_net_local_dgram, OID_AUTO, maxdgram, CTLFLAG_RW, 693 &unpdg_sendspace, 0, "Max datagram socket size"); 694 SYSCTL_INT(_net_local_dgram, OID_AUTO, recvspace, CTLFLAG_RW, 695 &unpdg_recvspace, 0, "Size of datagram socket receive buffer"); 696 697 SYSCTL_DECL(_net_local); 698 SYSCTL_INT(_net_local, OID_AUTO, inflight, CTLFLAG_RD, &unp_rights, 0, 699 "File descriptors in flight"); 700 701 static int 702 unp_attach(struct socket *so, struct pru_attach_info *ai) 703 { 704 struct unpcb *unp; 705 int error; 706 707 lwkt_gettoken(&unp_token); 708 709 if (so->so_snd.ssb_hiwat == 0 || so->so_rcv.ssb_hiwat == 0) { 710 switch (so->so_type) { 711 712 case SOCK_STREAM: 713 case SOCK_SEQPACKET: 714 error = soreserve(so, unpst_sendspace, unpst_recvspace, 715 ai->sb_rlimit); 716 break; 717 718 case SOCK_DGRAM: 719 error = soreserve(so, unpdg_sendspace, unpdg_recvspace, 720 ai->sb_rlimit); 721 break; 722 723 default: 724 panic("unp_attach"); 725 } 726 if (error) 727 goto failed; 728 } 729 unp = kmalloc(sizeof(*unp), M_UNPCB, M_NOWAIT|M_ZERO); 730 if (unp == NULL) { 731 error = ENOBUFS; 732 goto failed; 733 } 734 unp->unp_gencnt = ++unp_gencnt; 735 unp_count++; 736 LIST_INIT(&unp->unp_refs); 737 unp->unp_socket = so; 738 unp->unp_rvnode = ai->fd_rdir; /* jail cruft XXX JH */ 739 LIST_INSERT_HEAD(so->so_type == SOCK_DGRAM ? &unp_dhead 740 : &unp_shead, unp, unp_link); 741 so->so_pcb = (caddr_t)unp; 742 soreference(so); 743 error = 0; 744 failed: 745 lwkt_reltoken(&unp_token); 746 return error; 747 } 748 749 static void 750 unp_detach(struct unpcb *unp) 751 { 752 struct socket *so; 753 754 lwkt_gettoken(&unp_token); 755 756 LIST_REMOVE(unp, unp_link); 757 unp->unp_gencnt = ++unp_gencnt; 758 --unp_count; 759 if (unp->unp_vnode) { 760 unp->unp_vnode->v_socket = NULL; 761 vrele(unp->unp_vnode); 762 unp->unp_vnode = NULL; 763 } 764 if (unp->unp_conn) 765 unp_disconnect(unp); 766 while (!LIST_EMPTY(&unp->unp_refs)) 767 unp_drop(LIST_FIRST(&unp->unp_refs), ECONNRESET); 768 soisdisconnected(unp->unp_socket); 769 so = unp->unp_socket; 770 soreference(so); /* for delayed sorflush */ 771 so->so_pcb = NULL; 772 unp->unp_socket = NULL; 773 sofree(so); /* remove pcb ref */ 774 775 if (unp_rights) { 776 /* 777 * Normally the receive buffer is flushed later, 778 * in sofree, but if our receive buffer holds references 779 * to descriptors that are now garbage, we will dispose 780 * of those descriptor references after the garbage collector 781 * gets them (resulting in a "panic: closef: count < 0"). 782 */ 783 sorflush(so); 784 unp_gc(); 785 } 786 sofree(so); 787 lwkt_reltoken(&unp_token); 788 789 if (unp->unp_addr) 790 kfree(unp->unp_addr, M_SONAME); 791 kfree(unp, M_UNPCB); 792 } 793 794 static int 795 unp_bind(struct unpcb *unp, struct sockaddr *nam, struct thread *td) 796 { 797 struct proc *p = td->td_proc; 798 struct sockaddr_un *soun = (struct sockaddr_un *)nam; 799 struct vnode *vp; 800 struct vattr vattr; 801 int error, namelen; 802 struct nlookupdata nd; 803 char buf[SOCK_MAXADDRLEN]; 804 805 lwkt_gettoken(&unp_token); 806 if (unp->unp_vnode != NULL) { 807 error = EINVAL; 808 goto failed; 809 } 810 namelen = soun->sun_len - offsetof(struct sockaddr_un, sun_path); 811 if (namelen <= 0) { 812 error = EINVAL; 813 goto failed; 814 } 815 strncpy(buf, soun->sun_path, namelen); 816 buf[namelen] = 0; /* null-terminate the string */ 817 error = nlookup_init(&nd, buf, UIO_SYSSPACE, 818 NLC_LOCKVP | NLC_CREATE | NLC_REFDVP); 819 if (error == 0) 820 error = nlookup(&nd); 821 if (error == 0 && nd.nl_nch.ncp->nc_vp != NULL) 822 error = EADDRINUSE; 823 if (error) 824 goto done; 825 826 VATTR_NULL(&vattr); 827 vattr.va_type = VSOCK; 828 vattr.va_mode = (ACCESSPERMS & ~p->p_fd->fd_cmask); 829 error = VOP_NCREATE(&nd.nl_nch, nd.nl_dvp, &vp, nd.nl_cred, &vattr); 830 if (error == 0) { 831 vp->v_socket = unp->unp_socket; 832 unp->unp_vnode = vp; 833 unp->unp_addr = (struct sockaddr_un *)dup_sockaddr(nam); 834 vn_unlock(vp); 835 } 836 done: 837 nlookup_done(&nd); 838 failed: 839 lwkt_reltoken(&unp_token); 840 return (error); 841 } 842 843 static int 844 unp_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 845 { 846 struct proc *p = td->td_proc; 847 struct sockaddr_un *soun = (struct sockaddr_un *)nam; 848 struct vnode *vp; 849 struct socket *so2, *so3; 850 struct unpcb *unp, *unp2, *unp3; 851 int error, len; 852 struct nlookupdata nd; 853 char buf[SOCK_MAXADDRLEN]; 854 855 lwkt_gettoken(&unp_token); 856 857 len = nam->sa_len - offsetof(struct sockaddr_un, sun_path); 858 if (len <= 0) { 859 error = EINVAL; 860 goto failed; 861 } 862 strncpy(buf, soun->sun_path, len); 863 buf[len] = 0; 864 865 vp = NULL; 866 error = nlookup_init(&nd, buf, UIO_SYSSPACE, NLC_FOLLOW); 867 if (error == 0) 868 error = nlookup(&nd); 869 if (error == 0) 870 error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); 871 nlookup_done(&nd); 872 if (error) 873 goto failed; 874 875 if (vp->v_type != VSOCK) { 876 error = ENOTSOCK; 877 goto bad; 878 } 879 error = VOP_EACCESS(vp, VWRITE, p->p_ucred); 880 if (error) 881 goto bad; 882 so2 = vp->v_socket; 883 if (so2 == NULL) { 884 error = ECONNREFUSED; 885 goto bad; 886 } 887 if (so->so_type != so2->so_type) { 888 error = EPROTOTYPE; 889 goto bad; 890 } 891 if (so->so_proto->pr_flags & PR_CONNREQUIRED) { 892 if (!(so2->so_options & SO_ACCEPTCONN) || 893 (so3 = sonewconn(so2, 0)) == NULL) { 894 error = ECONNREFUSED; 895 goto bad; 896 } 897 unp = so->so_pcb; 898 unp2 = so2->so_pcb; 899 unp3 = so3->so_pcb; 900 if (unp2->unp_addr) 901 unp3->unp_addr = (struct sockaddr_un *) 902 dup_sockaddr((struct sockaddr *)unp2->unp_addr); 903 904 /* 905 * unp_peercred management: 906 * 907 * The connecter's (client's) credentials are copied 908 * from its process structure at the time of connect() 909 * (which is now). 910 */ 911 cru2x(p->p_ucred, &unp3->unp_peercred); 912 unp3->unp_flags |= UNP_HAVEPC; 913 /* 914 * The receiver's (server's) credentials are copied 915 * from the unp_peercred member of socket on which the 916 * former called listen(); unp_listen() cached that 917 * process's credentials at that time so we can use 918 * them now. 919 */ 920 KASSERT(unp2->unp_flags & UNP_HAVEPCCACHED, 921 ("unp_connect: listener without cached peercred")); 922 memcpy(&unp->unp_peercred, &unp2->unp_peercred, 923 sizeof(unp->unp_peercred)); 924 unp->unp_flags |= UNP_HAVEPC; 925 926 so2 = so3; 927 } 928 error = unp_connect2(so, so2); 929 bad: 930 vput(vp); 931 failed: 932 lwkt_reltoken(&unp_token); 933 return (error); 934 } 935 936 int 937 unp_connect2(struct socket *so, struct socket *so2) 938 { 939 struct unpcb *unp; 940 struct unpcb *unp2; 941 942 lwkt_gettoken(&unp_token); 943 unp = so->so_pcb; 944 if (so2->so_type != so->so_type) { 945 lwkt_reltoken(&unp_token); 946 return (EPROTOTYPE); 947 } 948 unp2 = so2->so_pcb; 949 unp->unp_conn = unp2; 950 951 switch (so->so_type) { 952 case SOCK_DGRAM: 953 LIST_INSERT_HEAD(&unp2->unp_refs, unp, unp_reflink); 954 soisconnected(so); 955 break; 956 957 case SOCK_STREAM: 958 case SOCK_SEQPACKET: 959 unp2->unp_conn = unp; 960 soisconnected(so); 961 soisconnected(so2); 962 break; 963 964 default: 965 panic("unp_connect2"); 966 } 967 lwkt_reltoken(&unp_token); 968 return (0); 969 } 970 971 static void 972 unp_disconnect(struct unpcb *unp) 973 { 974 struct unpcb *unp2; 975 976 lwkt_gettoken(&unp_token); 977 978 unp2 = unp->unp_conn; 979 if (unp2 == NULL) { 980 lwkt_reltoken(&unp_token); 981 return; 982 } 983 984 unp->unp_conn = NULL; 985 986 switch (unp->unp_socket->so_type) { 987 case SOCK_DGRAM: 988 LIST_REMOVE(unp, unp_reflink); 989 soclrstate(unp->unp_socket, SS_ISCONNECTED); 990 break; 991 case SOCK_STREAM: 992 case SOCK_SEQPACKET: 993 soisdisconnected(unp->unp_socket); 994 unp2->unp_conn = NULL; 995 soisdisconnected(unp2->unp_socket); 996 break; 997 } 998 lwkt_reltoken(&unp_token); 999 } 1000 1001 #ifdef notdef 1002 void 1003 unp_abort(struct unpcb *unp) 1004 { 1005 lwkt_gettoken(&unp_token); 1006 unp_detach(unp); 1007 lwkt_reltoken(&unp_token); 1008 } 1009 #endif 1010 1011 static int 1012 prison_unpcb(struct thread *td, struct unpcb *unp) 1013 { 1014 struct proc *p; 1015 1016 if (td == NULL) 1017 return (0); 1018 if ((p = td->td_proc) == NULL) 1019 return (0); 1020 if (!p->p_ucred->cr_prison) 1021 return (0); 1022 if (p->p_fd->fd_rdir == unp->unp_rvnode) 1023 return (0); 1024 return (1); 1025 } 1026 1027 static int 1028 unp_pcblist(SYSCTL_HANDLER_ARGS) 1029 { 1030 int error, i, n; 1031 struct unpcb *unp, **unp_list; 1032 unp_gen_t gencnt; 1033 struct unp_head *head; 1034 1035 head = ((intptr_t)arg1 == SOCK_DGRAM ? &unp_dhead : &unp_shead); 1036 1037 KKASSERT(curproc != NULL); 1038 1039 /* 1040 * The process of preparing the PCB list is too time-consuming and 1041 * resource-intensive to repeat twice on every request. 1042 */ 1043 if (req->oldptr == NULL) { 1044 n = unp_count; 1045 req->oldidx = (n + n/8) * sizeof(struct xunpcb); 1046 return 0; 1047 } 1048 1049 if (req->newptr != NULL) 1050 return EPERM; 1051 1052 lwkt_gettoken(&unp_token); 1053 1054 /* 1055 * OK, now we're committed to doing something. 1056 */ 1057 gencnt = unp_gencnt; 1058 n = unp_count; 1059 1060 unp_list = kmalloc(n * sizeof *unp_list, M_TEMP, M_WAITOK); 1061 1062 for (unp = LIST_FIRST(head), i = 0; unp && i < n; 1063 unp = LIST_NEXT(unp, unp_link)) { 1064 if (unp->unp_gencnt <= gencnt && !prison_unpcb(req->td, unp)) 1065 unp_list[i++] = unp; 1066 } 1067 n = i; /* in case we lost some during malloc */ 1068 1069 error = 0; 1070 for (i = 0; i < n; i++) { 1071 unp = unp_list[i]; 1072 if (unp->unp_gencnt <= gencnt) { 1073 struct xunpcb xu; 1074 xu.xu_len = sizeof xu; 1075 xu.xu_unpp = unp; 1076 /* 1077 * XXX - need more locking here to protect against 1078 * connect/disconnect races for SMP. 1079 */ 1080 if (unp->unp_addr) 1081 bcopy(unp->unp_addr, &xu.xu_addr, 1082 unp->unp_addr->sun_len); 1083 if (unp->unp_conn && unp->unp_conn->unp_addr) 1084 bcopy(unp->unp_conn->unp_addr, 1085 &xu.xu_caddr, 1086 unp->unp_conn->unp_addr->sun_len); 1087 bcopy(unp, &xu.xu_unp, sizeof *unp); 1088 sotoxsocket(unp->unp_socket, &xu.xu_socket); 1089 error = SYSCTL_OUT(req, &xu, sizeof xu); 1090 } 1091 } 1092 lwkt_reltoken(&unp_token); 1093 kfree(unp_list, M_TEMP); 1094 1095 return error; 1096 } 1097 1098 SYSCTL_PROC(_net_local_dgram, OID_AUTO, pcblist, CTLFLAG_RD, 1099 (caddr_t)(long)SOCK_DGRAM, 0, unp_pcblist, "S,xunpcb", 1100 "List of active local datagram sockets"); 1101 SYSCTL_PROC(_net_local_stream, OID_AUTO, pcblist, CTLFLAG_RD, 1102 (caddr_t)(long)SOCK_STREAM, 0, unp_pcblist, "S,xunpcb", 1103 "List of active local stream sockets"); 1104 SYSCTL_PROC(_net_local_seqpacket, OID_AUTO, pcblist, CTLFLAG_RD, 1105 (caddr_t)(long)SOCK_SEQPACKET, 0, unp_pcblist, "S,xunpcb", 1106 "List of active local seqpacket stream sockets"); 1107 1108 static void 1109 unp_shutdown(struct unpcb *unp) 1110 { 1111 struct socket *so; 1112 1113 if ((unp->unp_socket->so_type == SOCK_STREAM || 1114 unp->unp_socket->so_type == SOCK_SEQPACKET) && 1115 unp->unp_conn != NULL && (so = unp->unp_conn->unp_socket)) { 1116 socantrcvmore(so); 1117 } 1118 } 1119 1120 static void 1121 unp_drop(struct unpcb *unp, int err) 1122 { 1123 struct socket *so = unp->unp_socket; 1124 1125 so->so_error = err; 1126 unp_disconnect(unp); 1127 } 1128 1129 #ifdef notdef 1130 void 1131 unp_drain(void) 1132 { 1133 lwkt_gettoken(&unp_token); 1134 lwkt_reltoken(&unp_token); 1135 } 1136 #endif 1137 1138 int 1139 unp_externalize(struct mbuf *rights) 1140 { 1141 struct thread *td = curthread; 1142 struct proc *p = td->td_proc; /* XXX */ 1143 struct lwp *lp = td->td_lwp; 1144 struct cmsghdr *cm = mtod(rights, struct cmsghdr *); 1145 int *fdp; 1146 int i; 1147 struct file **rp; 1148 struct file *fp; 1149 int newfds = (cm->cmsg_len - (CMSG_DATA(cm) - (u_char *)cm)) 1150 / sizeof (struct file *); 1151 int f; 1152 1153 lwkt_gettoken(&unp_token); 1154 1155 /* 1156 * if the new FD's will not fit, then we free them all 1157 */ 1158 if (!fdavail(p, newfds)) { 1159 rp = (struct file **)CMSG_DATA(cm); 1160 for (i = 0; i < newfds; i++) { 1161 fp = *rp; 1162 /* 1163 * zero the pointer before calling unp_discard, 1164 * since it may end up in unp_gc().. 1165 */ 1166 *rp++ = 0; 1167 unp_discard(fp, NULL); 1168 } 1169 lwkt_reltoken(&unp_token); 1170 return (EMSGSIZE); 1171 } 1172 1173 /* 1174 * now change each pointer to an fd in the global table to 1175 * an integer that is the index to the local fd table entry 1176 * that we set up to point to the global one we are transferring. 1177 * If sizeof (struct file *) is bigger than or equal to sizeof int, 1178 * then do it in forward order. In that case, an integer will 1179 * always come in the same place or before its corresponding 1180 * struct file pointer. 1181 * If sizeof (struct file *) is smaller than sizeof int, then 1182 * do it in reverse order. 1183 */ 1184 if (sizeof (struct file *) >= sizeof (int)) { 1185 fdp = (int *)CMSG_DATA(cm); 1186 rp = (struct file **)CMSG_DATA(cm); 1187 for (i = 0; i < newfds; i++) { 1188 if (fdalloc(p, 0, &f)) 1189 panic("unp_externalize"); 1190 fp = *rp++; 1191 unp_fp_externalize(lp, fp, f); 1192 *fdp++ = f; 1193 } 1194 } else { 1195 fdp = (int *)CMSG_DATA(cm) + newfds - 1; 1196 rp = (struct file **)CMSG_DATA(cm) + newfds - 1; 1197 for (i = 0; i < newfds; i++) { 1198 if (fdalloc(p, 0, &f)) 1199 panic("unp_externalize"); 1200 fp = *rp--; 1201 unp_fp_externalize(lp, fp, f); 1202 *fdp-- = f; 1203 } 1204 } 1205 1206 /* 1207 * Adjust length, in case sizeof(struct file *) and sizeof(int) 1208 * differs. 1209 */ 1210 cm->cmsg_len = CMSG_LEN(newfds * sizeof(int)); 1211 rights->m_len = cm->cmsg_len; 1212 1213 lwkt_reltoken(&unp_token); 1214 return (0); 1215 } 1216 1217 static void 1218 unp_fp_externalize(struct lwp *lp, struct file *fp, int fd) 1219 { 1220 struct file *fx; 1221 int error; 1222 1223 lwkt_gettoken(&unp_token); 1224 1225 if (lp) { 1226 KKASSERT(fd >= 0); 1227 if (fp->f_flag & FREVOKED) { 1228 kprintf("Warning: revoked fp exiting unix socket\n"); 1229 fx = NULL; 1230 error = falloc(lp, &fx, NULL); 1231 if (error == 0) 1232 fsetfd(lp->lwp_proc->p_fd, fx, fd); 1233 else 1234 fsetfd(lp->lwp_proc->p_fd, NULL, fd); 1235 fdrop(fx); 1236 } else { 1237 fsetfd(lp->lwp_proc->p_fd, fp, fd); 1238 } 1239 } 1240 spin_lock(&unp_spin); 1241 fp->f_msgcount--; 1242 unp_rights--; 1243 spin_unlock(&unp_spin); 1244 fdrop(fp); 1245 1246 lwkt_reltoken(&unp_token); 1247 } 1248 1249 1250 void 1251 unp_init(void) 1252 { 1253 LIST_INIT(&unp_dhead); 1254 LIST_INIT(&unp_shead); 1255 spin_init(&unp_spin); 1256 } 1257 1258 static int 1259 unp_internalize(struct mbuf *control, struct thread *td) 1260 { 1261 struct proc *p = td->td_proc; 1262 struct filedesc *fdescp; 1263 struct cmsghdr *cm = mtod(control, struct cmsghdr *); 1264 struct file **rp; 1265 struct file *fp; 1266 int i, fd, *fdp; 1267 struct cmsgcred *cmcred; 1268 int oldfds; 1269 u_int newlen; 1270 int error; 1271 1272 KKASSERT(p); 1273 lwkt_gettoken(&unp_token); 1274 1275 fdescp = p->p_fd; 1276 if ((cm->cmsg_type != SCM_RIGHTS && cm->cmsg_type != SCM_CREDS) || 1277 cm->cmsg_level != SOL_SOCKET || 1278 CMSG_ALIGN(cm->cmsg_len) != control->m_len) { 1279 error = EINVAL; 1280 goto done; 1281 } 1282 1283 /* 1284 * Fill in credential information. 1285 */ 1286 if (cm->cmsg_type == SCM_CREDS) { 1287 cmcred = (struct cmsgcred *)CMSG_DATA(cm); 1288 cmcred->cmcred_pid = p->p_pid; 1289 cmcred->cmcred_uid = p->p_ucred->cr_ruid; 1290 cmcred->cmcred_gid = p->p_ucred->cr_rgid; 1291 cmcred->cmcred_euid = p->p_ucred->cr_uid; 1292 cmcred->cmcred_ngroups = MIN(p->p_ucred->cr_ngroups, 1293 CMGROUP_MAX); 1294 for (i = 0; i < cmcred->cmcred_ngroups; i++) 1295 cmcred->cmcred_groups[i] = p->p_ucred->cr_groups[i]; 1296 error = 0; 1297 goto done; 1298 } 1299 1300 /* 1301 * cmsghdr may not be aligned, do not allow calculation(s) to 1302 * go negative. 1303 */ 1304 if (cm->cmsg_len < CMSG_LEN(0)) { 1305 error = EINVAL; 1306 goto done; 1307 } 1308 1309 oldfds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof (int); 1310 1311 /* 1312 * check that all the FDs passed in refer to legal OPEN files 1313 * If not, reject the entire operation. 1314 */ 1315 fdp = (int *)CMSG_DATA(cm); 1316 for (i = 0; i < oldfds; i++) { 1317 fd = *fdp++; 1318 if ((unsigned)fd >= fdescp->fd_nfiles || 1319 fdescp->fd_files[fd].fp == NULL) { 1320 error = EBADF; 1321 goto done; 1322 } 1323 if (fdescp->fd_files[fd].fp->f_type == DTYPE_KQUEUE) { 1324 error = EOPNOTSUPP; 1325 goto done; 1326 } 1327 } 1328 /* 1329 * Now replace the integer FDs with pointers to 1330 * the associated global file table entry.. 1331 * Allocate a bigger buffer as necessary. But if an cluster is not 1332 * enough, return E2BIG. 1333 */ 1334 newlen = CMSG_LEN(oldfds * sizeof(struct file *)); 1335 if (newlen > MCLBYTES) { 1336 error = E2BIG; 1337 goto done; 1338 } 1339 if (newlen - control->m_len > M_TRAILINGSPACE(control)) { 1340 if (control->m_flags & M_EXT) { 1341 error = E2BIG; 1342 goto done; 1343 } 1344 MCLGET(control, MB_WAIT); 1345 if (!(control->m_flags & M_EXT)) { 1346 error = ENOBUFS; 1347 goto done; 1348 } 1349 1350 /* copy the data to the cluster */ 1351 memcpy(mtod(control, char *), cm, cm->cmsg_len); 1352 cm = mtod(control, struct cmsghdr *); 1353 } 1354 1355 /* 1356 * Adjust length, in case sizeof(struct file *) and sizeof(int) 1357 * differs. 1358 */ 1359 cm->cmsg_len = newlen; 1360 control->m_len = CMSG_ALIGN(newlen); 1361 1362 /* 1363 * Transform the file descriptors into struct file pointers. 1364 * If sizeof (struct file *) is bigger than or equal to sizeof int, 1365 * then do it in reverse order so that the int won't get until 1366 * we're done. 1367 * If sizeof (struct file *) is smaller than sizeof int, then 1368 * do it in forward order. 1369 */ 1370 if (sizeof (struct file *) >= sizeof (int)) { 1371 fdp = (int *)CMSG_DATA(cm) + oldfds - 1; 1372 rp = (struct file **)CMSG_DATA(cm) + oldfds - 1; 1373 for (i = 0; i < oldfds; i++) { 1374 fp = fdescp->fd_files[*fdp--].fp; 1375 *rp-- = fp; 1376 fhold(fp); 1377 spin_lock(&unp_spin); 1378 fp->f_msgcount++; 1379 unp_rights++; 1380 spin_unlock(&unp_spin); 1381 } 1382 } else { 1383 fdp = (int *)CMSG_DATA(cm); 1384 rp = (struct file **)CMSG_DATA(cm); 1385 for (i = 0; i < oldfds; i++) { 1386 fp = fdescp->fd_files[*fdp++].fp; 1387 *rp++ = fp; 1388 fhold(fp); 1389 spin_lock(&unp_spin); 1390 fp->f_msgcount++; 1391 unp_rights++; 1392 spin_unlock(&unp_spin); 1393 } 1394 } 1395 error = 0; 1396 done: 1397 lwkt_reltoken(&unp_token); 1398 return error; 1399 } 1400 1401 /* 1402 * Garbage collect in-transit file descriptors that get lost due to 1403 * loops (i.e. when a socket is sent to another process over itself, 1404 * and more complex situations). 1405 * 1406 * NOT MPSAFE - TODO socket flush code and maybe closef. Rest is MPSAFE. 1407 */ 1408 1409 struct unp_gc_info { 1410 struct file **extra_ref; 1411 struct file *locked_fp; 1412 int defer; 1413 int index; 1414 int maxindex; 1415 }; 1416 1417 static void 1418 unp_gc(void) 1419 { 1420 struct unp_gc_info info; 1421 static boolean_t unp_gcing; 1422 struct file **fpp; 1423 int i; 1424 1425 /* 1426 * Only one gc can be in-progress at any given moment 1427 */ 1428 spin_lock(&unp_spin); 1429 if (unp_gcing) { 1430 spin_unlock(&unp_spin); 1431 return; 1432 } 1433 unp_gcing = TRUE; 1434 spin_unlock(&unp_spin); 1435 1436 lwkt_gettoken(&unp_token); 1437 1438 /* 1439 * Before going through all this, set all FDs to be NOT defered 1440 * and NOT externally accessible (not marked). During the scan 1441 * a fd can be marked externally accessible but we may or may not 1442 * be able to immediately process it (controlled by FDEFER). 1443 * 1444 * If we loop sleep a bit. The complexity of the topology can cause 1445 * multiple loops. Also failure to acquire the socket's so_rcv 1446 * token can cause us to loop. 1447 */ 1448 allfiles_scan_exclusive(unp_gc_clearmarks, NULL); 1449 do { 1450 info.defer = 0; 1451 allfiles_scan_exclusive(unp_gc_checkmarks, &info); 1452 if (info.defer) 1453 tsleep(&info, 0, "gcagain", 1); 1454 } while (info.defer); 1455 1456 /* 1457 * We grab an extra reference to each of the file table entries 1458 * that are not otherwise accessible and then free the rights 1459 * that are stored in messages on them. 1460 * 1461 * The bug in the orginal code is a little tricky, so I'll describe 1462 * what's wrong with it here. 1463 * 1464 * It is incorrect to simply unp_discard each entry for f_msgcount 1465 * times -- consider the case of sockets A and B that contain 1466 * references to each other. On a last close of some other socket, 1467 * we trigger a gc since the number of outstanding rights (unp_rights) 1468 * is non-zero. If during the sweep phase the gc code un_discards, 1469 * we end up doing a (full) closef on the descriptor. A closef on A 1470 * results in the following chain. Closef calls soo_close, which 1471 * calls soclose. Soclose calls first (through the switch 1472 * uipc_usrreq) unp_detach, which re-invokes unp_gc. Unp_gc simply 1473 * returns because the previous instance had set unp_gcing, and 1474 * we return all the way back to soclose, which marks the socket 1475 * with SS_NOFDREF, and then calls sofree. Sofree calls sorflush 1476 * to free up the rights that are queued in messages on the socket A, 1477 * i.e., the reference on B. The sorflush calls via the dom_dispose 1478 * switch unp_dispose, which unp_scans with unp_discard. This second 1479 * instance of unp_discard just calls closef on B. 1480 * 1481 * Well, a similar chain occurs on B, resulting in a sorflush on B, 1482 * which results in another closef on A. Unfortunately, A is already 1483 * being closed, and the descriptor has already been marked with 1484 * SS_NOFDREF, and soclose panics at this point. 1485 * 1486 * Here, we first take an extra reference to each inaccessible 1487 * descriptor. Then, we call sorflush ourself, since we know 1488 * it is a Unix domain socket anyhow. After we destroy all the 1489 * rights carried in messages, we do a last closef to get rid 1490 * of our extra reference. This is the last close, and the 1491 * unp_detach etc will shut down the socket. 1492 * 1493 * 91/09/19, bsy@cs.cmu.edu 1494 */ 1495 info.extra_ref = kmalloc(256 * sizeof(struct file *), M_FILE, M_WAITOK); 1496 info.maxindex = 256; 1497 1498 do { 1499 /* 1500 * Look for matches 1501 */ 1502 info.index = 0; 1503 allfiles_scan_exclusive(unp_gc_checkrefs, &info); 1504 1505 /* 1506 * For each FD on our hit list, do the following two things 1507 */ 1508 for (i = info.index, fpp = info.extra_ref; --i >= 0; ++fpp) { 1509 struct file *tfp = *fpp; 1510 if (tfp->f_type == DTYPE_SOCKET && tfp->f_data != NULL) 1511 sorflush((struct socket *)(tfp->f_data)); 1512 } 1513 for (i = info.index, fpp = info.extra_ref; --i >= 0; ++fpp) 1514 closef(*fpp, NULL); 1515 } while (info.index == info.maxindex); 1516 1517 lwkt_reltoken(&unp_token); 1518 1519 kfree((caddr_t)info.extra_ref, M_FILE); 1520 unp_gcing = FALSE; 1521 } 1522 1523 /* 1524 * MPSAFE - NOTE: filehead list and file pointer spinlocked on entry 1525 */ 1526 static int 1527 unp_gc_checkrefs(struct file *fp, void *data) 1528 { 1529 struct unp_gc_info *info = data; 1530 1531 if (fp->f_count == 0) 1532 return(0); 1533 if (info->index == info->maxindex) 1534 return(-1); 1535 1536 /* 1537 * If all refs are from msgs, and it's not marked accessible 1538 * then it must be referenced from some unreachable cycle 1539 * of (shut-down) FDs, so include it in our 1540 * list of FDs to remove 1541 */ 1542 if (fp->f_count == fp->f_msgcount && !(fp->f_flag & FMARK)) { 1543 info->extra_ref[info->index++] = fp; 1544 fhold(fp); 1545 } 1546 return(0); 1547 } 1548 1549 /* 1550 * MPSAFE - NOTE: filehead list and file pointer spinlocked on entry 1551 */ 1552 static int 1553 unp_gc_clearmarks(struct file *fp, void *data __unused) 1554 { 1555 atomic_clear_int(&fp->f_flag, FMARK | FDEFER); 1556 return(0); 1557 } 1558 1559 /* 1560 * MPSAFE - NOTE: filehead list and file pointer spinlocked on entry 1561 */ 1562 static int 1563 unp_gc_checkmarks(struct file *fp, void *data) 1564 { 1565 struct unp_gc_info *info = data; 1566 struct socket *so; 1567 1568 /* 1569 * If the file is not open, skip it. Make sure it isn't marked 1570 * defered or we could loop forever, in case we somehow race 1571 * something. 1572 */ 1573 if (fp->f_count == 0) { 1574 if (fp->f_flag & FDEFER) 1575 atomic_clear_int(&fp->f_flag, FDEFER); 1576 return(0); 1577 } 1578 /* 1579 * If we already marked it as 'defer' in a 1580 * previous pass, then try process it this time 1581 * and un-mark it 1582 */ 1583 if (fp->f_flag & FDEFER) { 1584 atomic_clear_int(&fp->f_flag, FDEFER); 1585 } else { 1586 /* 1587 * if it's not defered, then check if it's 1588 * already marked.. if so skip it 1589 */ 1590 if (fp->f_flag & FMARK) 1591 return(0); 1592 /* 1593 * If all references are from messages 1594 * in transit, then skip it. it's not 1595 * externally accessible. 1596 */ 1597 if (fp->f_count == fp->f_msgcount) 1598 return(0); 1599 /* 1600 * If it got this far then it must be 1601 * externally accessible. 1602 */ 1603 atomic_set_int(&fp->f_flag, FMARK); 1604 } 1605 1606 /* 1607 * either it was defered, or it is externally 1608 * accessible and not already marked so. 1609 * Now check if it is possibly one of OUR sockets. 1610 */ 1611 if (fp->f_type != DTYPE_SOCKET || 1612 (so = (struct socket *)fp->f_data) == NULL) { 1613 return(0); 1614 } 1615 if (so->so_proto->pr_domain != &localdomain || 1616 !(so->so_proto->pr_flags & PR_RIGHTS)) { 1617 return(0); 1618 } 1619 1620 /* 1621 * So, Ok, it's one of our sockets and it IS externally accessible 1622 * (or was defered). Now we look to see if we hold any file 1623 * descriptors in its message buffers. Follow those links and mark 1624 * them as accessible too. 1625 * 1626 * We are holding multiple spinlocks here, if we cannot get the 1627 * token non-blocking defer until the next loop. 1628 */ 1629 info->locked_fp = fp; 1630 if (lwkt_trytoken(&so->so_rcv.ssb_token)) { 1631 unp_scan(so->so_rcv.ssb_mb, unp_mark, info); 1632 lwkt_reltoken(&so->so_rcv.ssb_token); 1633 } else { 1634 atomic_set_int(&fp->f_flag, FDEFER); 1635 ++info->defer; 1636 } 1637 return (0); 1638 } 1639 1640 /* 1641 * Scan all unix domain sockets and replace any revoked file pointers 1642 * found with the dummy file pointer fx. We don't worry about races 1643 * against file pointers being read out as those are handled in the 1644 * externalize code. 1645 */ 1646 1647 #define REVOKE_GC_MAXFILES 32 1648 1649 struct unp_revoke_gc_info { 1650 struct file *fx; 1651 struct file *fary[REVOKE_GC_MAXFILES]; 1652 int fcount; 1653 }; 1654 1655 void 1656 unp_revoke_gc(struct file *fx) 1657 { 1658 struct unp_revoke_gc_info info; 1659 int i; 1660 1661 lwkt_gettoken(&unp_token); 1662 info.fx = fx; 1663 do { 1664 info.fcount = 0; 1665 allfiles_scan_exclusive(unp_revoke_gc_check, &info); 1666 for (i = 0; i < info.fcount; ++i) 1667 unp_fp_externalize(NULL, info.fary[i], -1); 1668 } while (info.fcount == REVOKE_GC_MAXFILES); 1669 lwkt_reltoken(&unp_token); 1670 } 1671 1672 /* 1673 * Check for and replace revoked descriptors. 1674 * 1675 * WARNING: This routine is not allowed to block. 1676 */ 1677 static int 1678 unp_revoke_gc_check(struct file *fps, void *vinfo) 1679 { 1680 struct unp_revoke_gc_info *info = vinfo; 1681 struct file *fp; 1682 struct socket *so; 1683 struct mbuf *m0; 1684 struct mbuf *m; 1685 struct file **rp; 1686 struct cmsghdr *cm; 1687 int i; 1688 int qfds; 1689 1690 /* 1691 * Is this a unix domain socket with rights-passing abilities? 1692 */ 1693 if (fps->f_type != DTYPE_SOCKET) 1694 return (0); 1695 if ((so = (struct socket *)fps->f_data) == NULL) 1696 return(0); 1697 if (so->so_proto->pr_domain != &localdomain) 1698 return(0); 1699 if ((so->so_proto->pr_flags & PR_RIGHTS) == 0) 1700 return(0); 1701 1702 /* 1703 * Scan the mbufs for control messages and replace any revoked 1704 * descriptors we find. 1705 */ 1706 lwkt_gettoken(&so->so_rcv.ssb_token); 1707 m0 = so->so_rcv.ssb_mb; 1708 while (m0) { 1709 for (m = m0; m; m = m->m_next) { 1710 if (m->m_type != MT_CONTROL) 1711 continue; 1712 if (m->m_len < sizeof(*cm)) 1713 continue; 1714 cm = mtod(m, struct cmsghdr *); 1715 if (cm->cmsg_level != SOL_SOCKET || 1716 cm->cmsg_type != SCM_RIGHTS) { 1717 continue; 1718 } 1719 qfds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(void *); 1720 rp = (struct file **)CMSG_DATA(cm); 1721 for (i = 0; i < qfds; i++) { 1722 fp = rp[i]; 1723 if (fp->f_flag & FREVOKED) { 1724 kprintf("Warning: Removing revoked fp from unix domain socket queue\n"); 1725 fhold(info->fx); 1726 info->fx->f_msgcount++; 1727 unp_rights++; 1728 rp[i] = info->fx; 1729 info->fary[info->fcount++] = fp; 1730 } 1731 if (info->fcount == REVOKE_GC_MAXFILES) 1732 break; 1733 } 1734 if (info->fcount == REVOKE_GC_MAXFILES) 1735 break; 1736 } 1737 m0 = m0->m_nextpkt; 1738 if (info->fcount == REVOKE_GC_MAXFILES) 1739 break; 1740 } 1741 lwkt_reltoken(&so->so_rcv.ssb_token); 1742 1743 /* 1744 * Stop the scan if we filled up our array. 1745 */ 1746 if (info->fcount == REVOKE_GC_MAXFILES) 1747 return(-1); 1748 return(0); 1749 } 1750 1751 /* 1752 * Dispose of the fp's stored in a mbuf. 1753 * 1754 * The dds loop can cause additional fps to be entered onto the 1755 * list while it is running, flattening out the operation and avoiding 1756 * a deep kernel stack recursion. 1757 */ 1758 void 1759 unp_dispose(struct mbuf *m) 1760 { 1761 unp_defdiscard_t dds; 1762 1763 lwkt_gettoken(&unp_token); 1764 ++unp_defdiscard_nest; 1765 if (m) { 1766 unp_scan(m, unp_discard, NULL); 1767 } 1768 if (unp_defdiscard_nest == 1) { 1769 while ((dds = unp_defdiscard_base) != NULL) { 1770 unp_defdiscard_base = dds->next; 1771 closef(dds->fp, NULL); 1772 kfree(dds, M_UNPCB); 1773 } 1774 } 1775 --unp_defdiscard_nest; 1776 lwkt_reltoken(&unp_token); 1777 } 1778 1779 static int 1780 unp_listen(struct unpcb *unp, struct thread *td) 1781 { 1782 struct proc *p = td->td_proc; 1783 1784 KKASSERT(p); 1785 lwkt_gettoken(&unp_token); 1786 cru2x(p->p_ucred, &unp->unp_peercred); 1787 unp->unp_flags |= UNP_HAVEPCCACHED; 1788 lwkt_reltoken(&unp_token); 1789 return (0); 1790 } 1791 1792 static void 1793 unp_scan(struct mbuf *m0, void (*op)(struct file *, void *), void *data) 1794 { 1795 struct mbuf *m; 1796 struct file **rp; 1797 struct cmsghdr *cm; 1798 int i; 1799 int qfds; 1800 1801 while (m0) { 1802 for (m = m0; m; m = m->m_next) { 1803 if (m->m_type == MT_CONTROL && 1804 m->m_len >= sizeof(*cm)) { 1805 cm = mtod(m, struct cmsghdr *); 1806 if (cm->cmsg_level != SOL_SOCKET || 1807 cm->cmsg_type != SCM_RIGHTS) 1808 continue; 1809 qfds = (cm->cmsg_len - CMSG_LEN(0)) / 1810 sizeof(void *); 1811 rp = (struct file **)CMSG_DATA(cm); 1812 for (i = 0; i < qfds; i++) 1813 (*op)(*rp++, data); 1814 break; /* XXX, but saves time */ 1815 } 1816 } 1817 m0 = m0->m_nextpkt; 1818 } 1819 } 1820 1821 /* 1822 * Mark visibility. info->defer is recalculated on every pass. 1823 */ 1824 static void 1825 unp_mark(struct file *fp, void *data) 1826 { 1827 struct unp_gc_info *info = data; 1828 1829 if ((fp->f_flag & FMARK) == 0) { 1830 ++info->defer; 1831 atomic_set_int(&fp->f_flag, FMARK | FDEFER); 1832 } else if (fp->f_flag & FDEFER) { 1833 ++info->defer; 1834 } 1835 } 1836 1837 /* 1838 * Discard a fp previously held in a unix domain socket mbuf. To 1839 * avoid blowing out the kernel stack due to contrived chain-reactions 1840 * we may have to defer the operation to a higher procedural level. 1841 * 1842 * Caller holds unp_token 1843 */ 1844 static void 1845 unp_discard(struct file *fp, void *data __unused) 1846 { 1847 unp_defdiscard_t dds; 1848 1849 spin_lock(&unp_spin); 1850 fp->f_msgcount--; 1851 unp_rights--; 1852 spin_unlock(&unp_spin); 1853 1854 if (unp_defdiscard_nest) { 1855 dds = kmalloc(sizeof(*dds), M_UNPCB, M_WAITOK|M_ZERO); 1856 dds->fp = fp; 1857 dds->next = unp_defdiscard_base; 1858 unp_defdiscard_base = dds; 1859 } else { 1860 closef(fp, NULL); 1861 } 1862 } 1863 1864