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