1 /* $NetBSD: uipc_syscalls.c,v 1.200 2020/05/23 23:42:43 ad Exp $ */ 2 3 /*- 4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1982, 1986, 1989, 1990, 1993 34 * The Regents of the University of California. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 * 60 * @(#)uipc_syscalls.c 8.6 (Berkeley) 2/14/95 61 */ 62 63 #include <sys/cdefs.h> 64 __KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.200 2020/05/23 23:42:43 ad Exp $"); 65 66 #ifdef _KERNEL_OPT 67 #include "opt_pipe.h" 68 #include "opt_sctp.h" 69 #endif 70 71 #define MBUFTYPES 72 #include <sys/param.h> 73 #include <sys/systm.h> 74 #include <sys/filedesc.h> 75 #include <sys/proc.h> 76 #include <sys/file.h> 77 #include <sys/buf.h> 78 #include <sys/mbuf.h> 79 #include <sys/protosw.h> 80 #include <sys/socket.h> 81 #include <sys/socketvar.h> 82 #include <sys/signalvar.h> 83 #include <sys/un.h> 84 #include <sys/ktrace.h> 85 #include <sys/event.h> 86 #include <sys/atomic.h> 87 #include <sys/kauth.h> 88 89 #ifdef SCTP 90 #include <netinet/sctp_uio.h> 91 #include <netinet/sctp_peeloff.h> 92 #endif 93 94 #include <sys/mount.h> 95 #include <sys/syscallargs.h> 96 97 /* 98 * System call interface to the socket abstraction. 99 */ 100 extern const struct fileops socketops; 101 102 static int sockargs_sb(struct sockaddr_big *, const void *, socklen_t); 103 104 int 105 sys___socket30(struct lwp *l, const struct sys___socket30_args *uap, 106 register_t *retval) 107 { 108 /* { 109 syscallarg(int) domain; 110 syscallarg(int) type; 111 syscallarg(int) protocol; 112 } */ 113 int fd, error; 114 115 error = fsocreate(SCARG(uap, domain), NULL, SCARG(uap, type), 116 SCARG(uap, protocol), &fd); 117 if (error == 0) { 118 *retval = fd; 119 } 120 return error; 121 } 122 123 int 124 sys_bind(struct lwp *l, const struct sys_bind_args *uap, register_t *retval) 125 { 126 /* { 127 syscallarg(int) s; 128 syscallarg(const struct sockaddr *) name; 129 syscallarg(unsigned int) namelen; 130 } */ 131 int error; 132 struct sockaddr_big sb; 133 134 error = sockargs_sb(&sb, SCARG(uap, name), SCARG(uap, namelen)); 135 if (error) 136 return error; 137 138 return do_sys_bind(l, SCARG(uap, s), (struct sockaddr *)&sb); 139 } 140 141 int 142 do_sys_bind(struct lwp *l, int fd, struct sockaddr *nam) 143 { 144 struct socket *so; 145 int error; 146 147 if ((error = fd_getsock(fd, &so)) != 0) 148 return error; 149 error = sobind(so, nam, l); 150 fd_putfile(fd); 151 return error; 152 } 153 154 int 155 sys_listen(struct lwp *l, const struct sys_listen_args *uap, register_t *retval) 156 { 157 /* { 158 syscallarg(int) s; 159 syscallarg(int) backlog; 160 } */ 161 struct socket *so; 162 int error; 163 164 if ((error = fd_getsock(SCARG(uap, s), &so)) != 0) 165 return (error); 166 error = solisten(so, SCARG(uap, backlog), l); 167 fd_putfile(SCARG(uap, s)); 168 return error; 169 } 170 171 int 172 do_sys_accept(struct lwp *l, int sock, struct sockaddr *name, 173 register_t *new_sock, const sigset_t *mask, int flags, int clrflags) 174 { 175 file_t *fp, *fp2; 176 int error, fd; 177 struct socket *so, *so2; 178 short wakeup_state = 0; 179 180 if ((fp = fd_getfile(sock)) == NULL) 181 return EBADF; 182 if (fp->f_type != DTYPE_SOCKET) { 183 fd_putfile(sock); 184 return ENOTSOCK; 185 } 186 if ((error = fd_allocfile(&fp2, &fd)) != 0) { 187 fd_putfile(sock); 188 return error; 189 } 190 *new_sock = fd; 191 so = fp->f_socket; 192 solock(so); 193 194 if (__predict_false(mask)) 195 sigsuspendsetup(l, mask); 196 197 if (!(so->so_proto->pr_flags & PR_LISTEN)) { 198 error = EOPNOTSUPP; 199 goto bad; 200 } 201 if ((so->so_options & SO_ACCEPTCONN) == 0) { 202 error = EINVAL; 203 goto bad; 204 } 205 if ((so->so_state & SS_NBIO) && so->so_qlen == 0) { 206 error = EWOULDBLOCK; 207 goto bad; 208 } 209 while (so->so_qlen == 0 && so->so_error == 0) { 210 if (so->so_state & SS_CANTRCVMORE) { 211 so->so_error = ECONNABORTED; 212 break; 213 } 214 if (wakeup_state & SS_RESTARTSYS) { 215 error = ERESTART; 216 goto bad; 217 } 218 error = sowait(so, true, 0); 219 if (error) { 220 goto bad; 221 } 222 wakeup_state = so->so_state; 223 } 224 if (so->so_error) { 225 error = so->so_error; 226 so->so_error = 0; 227 goto bad; 228 } 229 /* connection has been removed from the listen queue */ 230 KNOTE(&so->so_rcv.sb_sel.sel_klist, NOTE_SUBMIT); 231 so2 = TAILQ_FIRST(&so->so_q); 232 if (soqremque(so2, 1) == 0) 233 panic("accept"); 234 fp2->f_type = DTYPE_SOCKET; 235 fp2->f_flag = (fp->f_flag & ~clrflags) | 236 ((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0)| 237 ((flags & SOCK_NOSIGPIPE) ? FNOSIGPIPE : 0); 238 fp2->f_ops = &socketops; 239 fp2->f_socket = so2; 240 if (fp2->f_flag & FNONBLOCK) 241 so2->so_state |= SS_NBIO; 242 else 243 so2->so_state &= ~SS_NBIO; 244 error = soaccept(so2, name); 245 so2->so_cred = kauth_cred_dup(so->so_cred); 246 sounlock(so); 247 if (error) { 248 /* an error occurred, free the file descriptor and mbuf */ 249 mutex_enter(&fp2->f_lock); 250 fp2->f_count++; 251 mutex_exit(&fp2->f_lock); 252 closef(fp2); 253 fd_abort(curproc, NULL, fd); 254 } else { 255 fd_set_exclose(l, fd, (flags & SOCK_CLOEXEC) != 0); 256 fd_affix(curproc, fp2, fd); 257 } 258 fd_putfile(sock); 259 if (__predict_false(mask)) 260 sigsuspendteardown(l); 261 return error; 262 bad: 263 sounlock(so); 264 fd_putfile(sock); 265 fd_abort(curproc, fp2, fd); 266 if (__predict_false(mask)) 267 sigsuspendteardown(l); 268 return error; 269 } 270 271 int 272 sys_accept(struct lwp *l, const struct sys_accept_args *uap, register_t *retval) 273 { 274 /* { 275 syscallarg(int) s; 276 syscallarg(struct sockaddr *) name; 277 syscallarg(unsigned int *) anamelen; 278 } */ 279 int error, fd; 280 struct sockaddr_big name; 281 282 name.sb_len = UCHAR_MAX; 283 error = do_sys_accept(l, SCARG(uap, s), (struct sockaddr *)&name, 284 retval, NULL, 0, 0); 285 if (error != 0) 286 return error; 287 error = copyout_sockname_sb(SCARG(uap, name), SCARG(uap, anamelen), 288 MSG_LENUSRSPACE, &name); 289 if (error != 0) { 290 fd = (int)*retval; 291 if (fd_getfile(fd) != NULL) 292 (void)fd_close(fd); 293 } 294 return error; 295 } 296 297 int 298 sys_paccept(struct lwp *l, const struct sys_paccept_args *uap, 299 register_t *retval) 300 { 301 /* { 302 syscallarg(int) s; 303 syscallarg(struct sockaddr *) name; 304 syscallarg(unsigned int *) anamelen; 305 syscallarg(const sigset_t *) mask; 306 syscallarg(int) flags; 307 } */ 308 int error, fd; 309 struct sockaddr_big name; 310 sigset_t *mask, amask; 311 312 if (SCARG(uap, mask) != NULL) { 313 error = copyin(SCARG(uap, mask), &amask, sizeof(amask)); 314 if (error) 315 return error; 316 mask = &amask; 317 } else 318 mask = NULL; 319 320 name.sb_len = UCHAR_MAX; 321 error = do_sys_accept(l, SCARG(uap, s), (struct sockaddr *)&name, 322 retval, mask, SCARG(uap, flags), FNONBLOCK); 323 if (error != 0) 324 return error; 325 error = copyout_sockname_sb(SCARG(uap, name), SCARG(uap, anamelen), 326 MSG_LENUSRSPACE, &name); 327 if (error != 0) { 328 fd = (int)*retval; 329 if (fd_getfile(fd) != NULL) 330 (void)fd_close(fd); 331 } 332 return error; 333 } 334 335 int 336 sys_connect(struct lwp *l, const struct sys_connect_args *uap, 337 register_t *retval) 338 { 339 /* { 340 syscallarg(int) s; 341 syscallarg(const struct sockaddr *) name; 342 syscallarg(unsigned int) namelen; 343 } */ 344 int error; 345 struct sockaddr_big sbig; 346 347 error = sockargs_sb(&sbig, SCARG(uap, name), SCARG(uap, namelen)); 348 if (error) 349 return error; 350 return do_sys_connect(l, SCARG(uap, s), (struct sockaddr *)&sbig); 351 } 352 353 int 354 do_sys_connect(struct lwp *l, int fd, struct sockaddr *nam) 355 { 356 struct socket *so; 357 int error; 358 int interrupted = 0; 359 360 if ((error = fd_getsock(fd, &so)) != 0) { 361 return (error); 362 } 363 solock(so); 364 if ((so->so_state & SS_ISCONNECTING) != 0) { 365 error = EALREADY; 366 goto out; 367 } 368 369 error = soconnect(so, nam, l); 370 if (error) 371 goto bad; 372 if ((so->so_state & (SS_NBIO|SS_ISCONNECTING)) == 373 (SS_NBIO|SS_ISCONNECTING)) { 374 error = EINPROGRESS; 375 goto out; 376 } 377 while ((so->so_state & SS_ISCONNECTING) != 0 && so->so_error == 0) { 378 error = sowait(so, true, 0); 379 if (__predict_false((so->so_state & SS_ISABORTING) != 0)) { 380 error = EPIPE; 381 interrupted = 1; 382 break; 383 } 384 if (error) { 385 if (error == EINTR || error == ERESTART) 386 interrupted = 1; 387 break; 388 } 389 } 390 if (error == 0) { 391 error = so->so_error; 392 so->so_error = 0; 393 } 394 bad: 395 if (!interrupted) 396 so->so_state &= ~SS_ISCONNECTING; 397 if (error == ERESTART) 398 error = EINTR; 399 out: 400 sounlock(so); 401 fd_putfile(fd); 402 return error; 403 } 404 405 static int 406 makesocket(struct lwp *l, file_t **fp, int *fd, int flags, int type, 407 int domain, int proto, struct socket *soo) 408 { 409 struct socket *so; 410 int error; 411 412 if ((error = socreate(domain, &so, type, proto, l, soo)) != 0) { 413 return error; 414 } 415 if (flags & SOCK_NONBLOCK) { 416 so->so_state |= SS_NBIO; 417 } 418 419 if ((error = fd_allocfile(fp, fd)) != 0) { 420 soclose(so); 421 return error; 422 } 423 fd_set_exclose(l, *fd, (flags & SOCK_CLOEXEC) != 0); 424 (*fp)->f_flag = FREAD|FWRITE| 425 ((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0)| 426 ((flags & SOCK_NOSIGPIPE) ? FNOSIGPIPE : 0); 427 (*fp)->f_type = DTYPE_SOCKET; 428 (*fp)->f_ops = &socketops; 429 (*fp)->f_socket = so; 430 return 0; 431 } 432 433 int 434 sys_socketpair(struct lwp *l, const struct sys_socketpair_args *uap, 435 register_t *retval) 436 { 437 /* { 438 syscallarg(int) domain; 439 syscallarg(int) type; 440 syscallarg(int) protocol; 441 syscallarg(int *) rsv; 442 } */ 443 file_t *fp1, *fp2; 444 struct socket *so1, *so2; 445 int fd, error, sv[2]; 446 proc_t *p = curproc; 447 int flags = SCARG(uap, type) & SOCK_FLAGS_MASK; 448 int type = SCARG(uap, type) & ~SOCK_FLAGS_MASK; 449 int domain = SCARG(uap, domain); 450 int proto = SCARG(uap, protocol); 451 452 error = makesocket(l, &fp1, &fd, flags, type, domain, proto, NULL); 453 if (error) 454 return error; 455 so1 = fp1->f_socket; 456 sv[0] = fd; 457 458 error = makesocket(l, &fp2, &fd, flags, type, domain, proto, so1); 459 if (error) 460 goto out; 461 so2 = fp2->f_socket; 462 sv[1] = fd; 463 464 solock(so1); 465 error = soconnect2(so1, so2); 466 if (error == 0 && type == SOCK_DGRAM) { 467 /* 468 * Datagram socket connection is asymmetric. 469 */ 470 error = soconnect2(so2, so1); 471 } 472 sounlock(so1); 473 474 if (error == 0) 475 error = copyout(sv, SCARG(uap, rsv), sizeof(sv)); 476 if (error == 0) { 477 fd_affix(p, fp2, sv[1]); 478 fd_affix(p, fp1, sv[0]); 479 return 0; 480 } 481 fd_abort(p, fp2, sv[1]); 482 (void)soclose(so2); 483 out: 484 fd_abort(p, fp1, sv[0]); 485 (void)soclose(so1); 486 return error; 487 } 488 489 int 490 sys_sendto(struct lwp *l, const struct sys_sendto_args *uap, 491 register_t *retval) 492 { 493 /* { 494 syscallarg(int) s; 495 syscallarg(const void *) buf; 496 syscallarg(size_t) len; 497 syscallarg(int) flags; 498 syscallarg(const struct sockaddr *) to; 499 syscallarg(unsigned int) tolen; 500 } */ 501 struct msghdr msg; 502 struct iovec aiov; 503 504 msg.msg_name = __UNCONST(SCARG(uap, to)); /* XXXUNCONST kills const */ 505 msg.msg_namelen = SCARG(uap, tolen); 506 msg.msg_iov = &aiov; 507 msg.msg_iovlen = 1; 508 msg.msg_control = NULL; 509 msg.msg_flags = 0; 510 aiov.iov_base = __UNCONST(SCARG(uap, buf)); /* XXXUNCONST kills const */ 511 aiov.iov_len = SCARG(uap, len); 512 return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), 513 retval); 514 } 515 516 int 517 sys_sendmsg(struct lwp *l, const struct sys_sendmsg_args *uap, 518 register_t *retval) 519 { 520 /* { 521 syscallarg(int) s; 522 syscallarg(const struct msghdr *) msg; 523 syscallarg(int) flags; 524 } */ 525 struct msghdr msg; 526 int error; 527 528 error = copyin(SCARG(uap, msg), &msg, sizeof(msg)); 529 if (error) 530 return (error); 531 532 msg.msg_flags = MSG_IOVUSRSPACE; 533 return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), 534 retval); 535 } 536 537 int 538 do_sys_sendmsg_so(struct lwp *l, int s, struct socket *so, file_t *fp, 539 struct msghdr *mp, int flags, register_t *retsize) 540 { 541 542 struct iovec aiov[UIO_SMALLIOV], *iov = aiov, *tiov, *ktriov = NULL; 543 struct sockaddr *sa = NULL; 544 struct mbuf *to, *control; 545 struct uio auio; 546 size_t len, iovsz; 547 int i, error; 548 549 ktrkuser("msghdr", mp, sizeof(*mp)); 550 551 /* If the caller passed us stuff in mbufs, we must free them. */ 552 to = (mp->msg_flags & MSG_NAMEMBUF) ? mp->msg_name : NULL; 553 control = (mp->msg_flags & MSG_CONTROLMBUF) ? mp->msg_control : NULL; 554 iovsz = mp->msg_iovlen * sizeof(struct iovec); 555 556 if (mp->msg_flags & MSG_IOVUSRSPACE) { 557 if ((unsigned int)mp->msg_iovlen > UIO_SMALLIOV) { 558 if ((unsigned int)mp->msg_iovlen > IOV_MAX) { 559 error = EMSGSIZE; 560 goto bad; 561 } 562 iov = kmem_alloc(iovsz, KM_SLEEP); 563 } 564 if (mp->msg_iovlen != 0) { 565 error = copyin(mp->msg_iov, iov, iovsz); 566 if (error) 567 goto bad; 568 } 569 auio.uio_iov = iov; 570 } else 571 auio.uio_iov = mp->msg_iov; 572 573 auio.uio_iovcnt = mp->msg_iovlen; 574 auio.uio_rw = UIO_WRITE; 575 auio.uio_offset = 0; /* XXX */ 576 auio.uio_resid = 0; 577 KASSERT(l == curlwp); 578 auio.uio_vmspace = l->l_proc->p_vmspace; 579 580 tiov = auio.uio_iov; 581 for (i = 0; i < auio.uio_iovcnt; i++, tiov++) { 582 /* 583 * Writes return ssize_t because -1 is returned on error. 584 * Therefore, we must restrict the length to SSIZE_MAX to 585 * avoid garbage return values. 586 */ 587 auio.uio_resid += tiov->iov_len; 588 if (tiov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) { 589 error = EINVAL; 590 goto bad; 591 } 592 } 593 594 if (mp->msg_name && to == NULL) { 595 error = sockargs(&to, mp->msg_name, mp->msg_namelen, 596 UIO_USERSPACE, MT_SONAME); 597 if (error) 598 goto bad; 599 } 600 601 if (mp->msg_control) { 602 if (mp->msg_controllen < CMSG_ALIGN(sizeof(struct cmsghdr))) { 603 error = EINVAL; 604 goto bad; 605 } 606 if (control == NULL) { 607 error = sockargs(&control, mp->msg_control, 608 mp->msg_controllen, UIO_USERSPACE, MT_CONTROL); 609 if (error) 610 goto bad; 611 } 612 } 613 614 if (ktrpoint(KTR_GENIO) && iovsz > 0) { 615 ktriov = kmem_alloc(iovsz, KM_SLEEP); 616 memcpy(ktriov, auio.uio_iov, iovsz); 617 } 618 619 if (mp->msg_name) 620 MCLAIM(to, so->so_mowner); 621 if (mp->msg_control) 622 MCLAIM(control, so->so_mowner); 623 624 if (to) { 625 sa = mtod(to, struct sockaddr *); 626 } 627 628 len = auio.uio_resid; 629 error = (*so->so_send)(so, sa, &auio, NULL, control, flags, l); 630 /* Protocol is responsible for freeing 'control' */ 631 control = NULL; 632 633 if (error) { 634 if (auio.uio_resid != len && (error == ERESTART || 635 error == EINTR || error == EWOULDBLOCK)) 636 error = 0; 637 if (error == EPIPE && (fp->f_flag & FNOSIGPIPE) == 0 && 638 (flags & MSG_NOSIGNAL) == 0) { 639 mutex_enter(&proc_lock); 640 psignal(l->l_proc, SIGPIPE); 641 mutex_exit(&proc_lock); 642 } 643 } 644 if (error == 0) 645 *retsize = len - auio.uio_resid; 646 647 bad: 648 if (ktriov != NULL) { 649 ktrgeniov(s, UIO_WRITE, ktriov, *retsize, error); 650 kmem_free(ktriov, iovsz); 651 } 652 653 if (iov != aiov) 654 kmem_free(iov, iovsz); 655 if (to) 656 m_freem(to); 657 if (control) 658 m_freem(control); 659 660 return error; 661 } 662 663 int 664 do_sys_sendmsg(struct lwp *l, int s, struct msghdr *mp, int flags, 665 register_t *retsize) 666 { 667 int error; 668 struct socket *so; 669 file_t *fp; 670 671 if ((error = fd_getsock1(s, &so, &fp)) != 0) { 672 /* We have to free msg_name and msg_control ourselves */ 673 if (mp->msg_flags & MSG_NAMEMBUF) 674 m_freem(mp->msg_name); 675 if (mp->msg_flags & MSG_CONTROLMBUF) 676 m_freem(mp->msg_control); 677 return error; 678 } 679 error = do_sys_sendmsg_so(l, s, so, fp, mp, flags, retsize); 680 /* msg_name and msg_control freed */ 681 fd_putfile(s); 682 return error; 683 } 684 685 int 686 sys_recvfrom(struct lwp *l, const struct sys_recvfrom_args *uap, 687 register_t *retval) 688 { 689 /* { 690 syscallarg(int) s; 691 syscallarg(void *) buf; 692 syscallarg(size_t) len; 693 syscallarg(int) flags; 694 syscallarg(struct sockaddr *) from; 695 syscallarg(unsigned int *) fromlenaddr; 696 } */ 697 struct msghdr msg; 698 struct iovec aiov; 699 int error; 700 struct mbuf *from; 701 702 msg.msg_name = NULL; 703 msg.msg_iov = &aiov; 704 msg.msg_iovlen = 1; 705 aiov.iov_base = SCARG(uap, buf); 706 aiov.iov_len = SCARG(uap, len); 707 msg.msg_control = NULL; 708 msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS; 709 710 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, NULL, retval); 711 if (error != 0) 712 return error; 713 714 error = copyout_sockname(SCARG(uap, from), SCARG(uap, fromlenaddr), 715 MSG_LENUSRSPACE, from); 716 if (from != NULL) 717 m_free(from); 718 return error; 719 } 720 721 int 722 sys_recvmsg(struct lwp *l, const struct sys_recvmsg_args *uap, 723 register_t *retval) 724 { 725 /* { 726 syscallarg(int) s; 727 syscallarg(struct msghdr *) msg; 728 syscallarg(int) flags; 729 } */ 730 struct msghdr msg; 731 int error; 732 struct mbuf *from, *control; 733 734 error = copyin(SCARG(uap, msg), &msg, sizeof(msg)); 735 if (error) 736 return error; 737 738 msg.msg_flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE; 739 740 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, 741 msg.msg_control != NULL ? &control : NULL, retval); 742 if (error != 0) 743 return error; 744 745 if (msg.msg_control != NULL) 746 error = copyout_msg_control(l, &msg, control); 747 748 if (error == 0) 749 error = copyout_sockname(msg.msg_name, &msg.msg_namelen, 0, 750 from); 751 if (from != NULL) 752 m_free(from); 753 if (error == 0) { 754 ktrkuser("msghdr", &msg, sizeof(msg)); 755 error = copyout(&msg, SCARG(uap, msg), sizeof(msg)); 756 } 757 758 return error; 759 } 760 761 int 762 sys_sendmmsg(struct lwp *l, const struct sys_sendmmsg_args *uap, 763 register_t *retval) 764 { 765 /* { 766 syscallarg(int) s; 767 syscallarg(struct mmsghdr *) mmsg; 768 syscallarg(unsigned int) vlen; 769 syscallarg(unsigned int) flags; 770 } */ 771 struct mmsghdr mmsg; 772 struct socket *so; 773 file_t *fp; 774 struct msghdr *msg = &mmsg.msg_hdr; 775 int error, s; 776 unsigned int vlen, flags, dg; 777 778 s = SCARG(uap, s); 779 if ((error = fd_getsock1(s, &so, &fp)) != 0) 780 return error; 781 782 vlen = SCARG(uap, vlen); 783 if (vlen > 1024) 784 vlen = 1024; 785 786 flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE; 787 788 for (dg = 0; dg < vlen;) { 789 error = copyin(SCARG(uap, mmsg) + dg, &mmsg, sizeof(mmsg)); 790 if (error) 791 break; 792 793 msg->msg_flags = flags; 794 795 error = do_sys_sendmsg_so(l, s, so, fp, msg, flags, retval); 796 if (error) 797 break; 798 799 ktrkuser("msghdr", msg, sizeof(*msg)); 800 mmsg.msg_len = *retval; 801 error = copyout(&mmsg, SCARG(uap, mmsg) + dg, sizeof(mmsg)); 802 if (error) 803 break; 804 dg++; 805 806 } 807 808 *retval = dg; 809 810 fd_putfile(s); 811 812 /* 813 * If we succeeded at least once, return 0. 814 */ 815 if (dg) 816 return 0; 817 return error; 818 } 819 820 /* 821 * Adjust for a truncated SCM_RIGHTS control message. 822 * This means closing any file descriptors that aren't present 823 * in the returned buffer. 824 * m is the mbuf holding the (already externalized) SCM_RIGHTS message. 825 */ 826 static void 827 free_rights(struct mbuf *m) 828 { 829 struct cmsghdr *cm; 830 int *fdv; 831 unsigned int nfds, i; 832 833 KASSERT(sizeof(*cm) <= m->m_len); 834 cm = mtod(m, struct cmsghdr *); 835 836 KASSERT(CMSG_ALIGN(sizeof(*cm)) <= cm->cmsg_len); 837 KASSERT(cm->cmsg_len <= m->m_len); 838 nfds = (cm->cmsg_len - CMSG_ALIGN(sizeof(*cm))) / sizeof(int); 839 fdv = (int *)CMSG_DATA(cm); 840 841 for (i = 0; i < nfds; i++) 842 if (fd_getfile(fdv[i]) != NULL) 843 (void)fd_close(fdv[i]); 844 } 845 846 void 847 free_control_mbuf(struct lwp *l, struct mbuf *control, struct mbuf *uncopied) 848 { 849 struct mbuf *next; 850 struct cmsghdr *cmsg; 851 bool do_free_rights = false; 852 853 while (control != NULL) { 854 cmsg = mtod(control, struct cmsghdr *); 855 if (control == uncopied) 856 do_free_rights = true; 857 if (do_free_rights && cmsg->cmsg_level == SOL_SOCKET 858 && cmsg->cmsg_type == SCM_RIGHTS) 859 free_rights(control); 860 next = control->m_next; 861 m_free(control); 862 control = next; 863 } 864 } 865 866 /* Copy socket control/CMSG data to user buffer, frees the mbuf */ 867 int 868 copyout_msg_control(struct lwp *l, struct msghdr *mp, struct mbuf *control) 869 { 870 int i, len, error = 0; 871 struct cmsghdr *cmsg; 872 struct mbuf *m; 873 char *q; 874 875 len = mp->msg_controllen; 876 if (len <= 0 || control == 0) { 877 mp->msg_controllen = 0; 878 free_control_mbuf(l, control, control); 879 return 0; 880 } 881 882 q = (char *)mp->msg_control; 883 884 for (m = control; m != NULL; ) { 885 cmsg = mtod(m, struct cmsghdr *); 886 i = m->m_len; 887 if (len < i) { 888 mp->msg_flags |= MSG_CTRUNC; 889 if (cmsg->cmsg_level == SOL_SOCKET 890 && cmsg->cmsg_type == SCM_RIGHTS) 891 /* Do not truncate me ... */ 892 break; 893 i = len; 894 } 895 error = copyout(mtod(m, void *), q, i); 896 ktrkuser(mbuftypes[MT_CONTROL], cmsg, cmsg->cmsg_len); 897 if (error != 0) { 898 /* We must free all the SCM_RIGHTS */ 899 m = control; 900 break; 901 } 902 m = m->m_next; 903 if (m) 904 i = ALIGN(i); 905 q += i; 906 len -= i; 907 if (len <= 0) 908 break; 909 } 910 911 free_control_mbuf(l, control, m); 912 913 mp->msg_controllen = q - (char *)mp->msg_control; 914 return error; 915 } 916 917 int 918 do_sys_recvmsg_so(struct lwp *l, int s, struct socket *so, struct msghdr *mp, 919 struct mbuf **from, struct mbuf **control, register_t *retsize) 920 { 921 struct iovec aiov[UIO_SMALLIOV], *iov = aiov, *tiov, *ktriov = NULL; 922 struct uio auio; 923 size_t len, iovsz; 924 int i, error; 925 926 ktrkuser("msghdr", mp, sizeof(*mp)); 927 928 *from = NULL; 929 if (control != NULL) 930 *control = NULL; 931 932 iovsz = mp->msg_iovlen * sizeof(struct iovec); 933 934 if (mp->msg_flags & MSG_IOVUSRSPACE) { 935 if ((unsigned int)mp->msg_iovlen > UIO_SMALLIOV) { 936 if ((unsigned int)mp->msg_iovlen > IOV_MAX) { 937 error = EMSGSIZE; 938 goto out; 939 } 940 iov = kmem_alloc(iovsz, KM_SLEEP); 941 } 942 if (mp->msg_iovlen != 0) { 943 error = copyin(mp->msg_iov, iov, iovsz); 944 if (error) 945 goto out; 946 } 947 auio.uio_iov = iov; 948 } else 949 auio.uio_iov = mp->msg_iov; 950 auio.uio_iovcnt = mp->msg_iovlen; 951 auio.uio_rw = UIO_READ; 952 auio.uio_offset = 0; /* XXX */ 953 auio.uio_resid = 0; 954 KASSERT(l == curlwp); 955 auio.uio_vmspace = l->l_proc->p_vmspace; 956 957 tiov = auio.uio_iov; 958 for (i = 0; i < auio.uio_iovcnt; i++, tiov++) { 959 /* 960 * Reads return ssize_t because -1 is returned on error. 961 * Therefore we must restrict the length to SSIZE_MAX to 962 * avoid garbage return values. 963 */ 964 auio.uio_resid += tiov->iov_len; 965 if (tiov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) { 966 error = EINVAL; 967 goto out; 968 } 969 } 970 971 if (ktrpoint(KTR_GENIO) && iovsz > 0) { 972 ktriov = kmem_alloc(iovsz, KM_SLEEP); 973 memcpy(ktriov, auio.uio_iov, iovsz); 974 } 975 976 len = auio.uio_resid; 977 mp->msg_flags &= MSG_USERFLAGS; 978 error = (*so->so_receive)(so, from, &auio, NULL, control, 979 &mp->msg_flags); 980 KASSERT(*from == NULL || (*from)->m_next == NULL); 981 len -= auio.uio_resid; 982 *retsize = len; 983 if (error != 0 && len != 0 984 && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) 985 /* Some data transferred */ 986 error = 0; 987 988 if (ktriov != NULL) { 989 ktrgeniov(s, UIO_READ, ktriov, len, error); 990 kmem_free(ktriov, iovsz); 991 } 992 993 if (error != 0) { 994 m_freem(*from); 995 *from = NULL; 996 if (control != NULL) { 997 free_control_mbuf(l, *control, *control); 998 *control = NULL; 999 } 1000 } 1001 out: 1002 if (iov != aiov) 1003 kmem_free(iov, iovsz); 1004 return error; 1005 } 1006 1007 1008 int 1009 do_sys_recvmsg(struct lwp *l, int s, struct msghdr *mp, 1010 struct mbuf **from, struct mbuf **control, register_t *retsize) 1011 { 1012 int error; 1013 struct socket *so; 1014 1015 if ((error = fd_getsock(s, &so)) != 0) 1016 return error; 1017 error = do_sys_recvmsg_so(l, s, so, mp, from, control, retsize); 1018 fd_putfile(s); 1019 return error; 1020 } 1021 1022 int 1023 sys_recvmmsg(struct lwp *l, const struct sys_recvmmsg_args *uap, 1024 register_t *retval) 1025 { 1026 /* { 1027 syscallarg(int) s; 1028 syscallarg(struct mmsghdr *) mmsg; 1029 syscallarg(unsigned int) vlen; 1030 syscallarg(unsigned int) flags; 1031 syscallarg(struct timespec *) timeout; 1032 } */ 1033 struct mmsghdr mmsg; 1034 struct socket *so; 1035 struct msghdr *msg = &mmsg.msg_hdr; 1036 int error, s; 1037 struct mbuf *from, *control; 1038 struct timespec ts, now; 1039 unsigned int vlen, flags, dg; 1040 1041 if (SCARG(uap, timeout)) { 1042 if ((error = copyin(SCARG(uap, timeout), &ts, sizeof(ts))) != 0) 1043 return error; 1044 getnanotime(&now); 1045 timespecadd(&now, &ts, &ts); 1046 } 1047 1048 s = SCARG(uap, s); 1049 if ((error = fd_getsock(s, &so)) != 0) 1050 return error; 1051 1052 /* 1053 * If so->so_rerror holds a deferred error return it now. 1054 */ 1055 if (so->so_rerror) { 1056 error = so->so_rerror; 1057 so->so_rerror = 0; 1058 fd_putfile(s); 1059 return error; 1060 } 1061 1062 vlen = SCARG(uap, vlen); 1063 if (vlen > 1024) 1064 vlen = 1024; 1065 1066 from = NULL; 1067 flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE; 1068 1069 for (dg = 0; dg < vlen;) { 1070 error = copyin(SCARG(uap, mmsg) + dg, &mmsg, sizeof(mmsg)); 1071 if (error) 1072 break; 1073 1074 msg->msg_flags = flags & ~MSG_WAITFORONE; 1075 1076 if (from != NULL) { 1077 m_free(from); 1078 from = NULL; 1079 } 1080 1081 error = do_sys_recvmsg_so(l, s, so, msg, &from, 1082 msg->msg_control != NULL ? &control : NULL, retval); 1083 if (error) { 1084 if (error == EAGAIN && dg > 0) 1085 error = 0; 1086 break; 1087 } 1088 1089 if (msg->msg_control != NULL) 1090 error = copyout_msg_control(l, msg, control); 1091 if (error) 1092 break; 1093 1094 error = copyout_sockname(msg->msg_name, &msg->msg_namelen, 0, 1095 from); 1096 if (error) 1097 break; 1098 1099 ktrkuser("msghdr", msg, sizeof *msg); 1100 mmsg.msg_len = *retval; 1101 1102 error = copyout(&mmsg, SCARG(uap, mmsg) + dg, sizeof(mmsg)); 1103 if (error) 1104 break; 1105 1106 dg++; 1107 if (msg->msg_flags & MSG_OOB) 1108 break; 1109 1110 if (SCARG(uap, timeout)) { 1111 getnanotime(&now); 1112 timespecsub(&now, &ts, &now); 1113 if (now.tv_sec > 0) 1114 break; 1115 } 1116 1117 if (flags & MSG_WAITFORONE) 1118 flags |= MSG_DONTWAIT; 1119 1120 } 1121 1122 if (from != NULL) 1123 m_free(from); 1124 1125 *retval = dg; 1126 1127 /* 1128 * If we succeeded at least once, return 0, hopefully so->so_rerror 1129 * will catch it next time. 1130 */ 1131 if (error && dg > 0) { 1132 so->so_rerror = error; 1133 error = 0; 1134 } 1135 1136 fd_putfile(s); 1137 1138 return error; 1139 } 1140 1141 int 1142 sys_shutdown(struct lwp *l, const struct sys_shutdown_args *uap, 1143 register_t *retval) 1144 { 1145 /* { 1146 syscallarg(int) s; 1147 syscallarg(int) how; 1148 } */ 1149 struct socket *so; 1150 int error; 1151 1152 if ((error = fd_getsock(SCARG(uap, s), &so)) != 0) 1153 return error; 1154 solock(so); 1155 error = soshutdown(so, SCARG(uap, how)); 1156 sounlock(so); 1157 fd_putfile(SCARG(uap, s)); 1158 return error; 1159 } 1160 1161 int 1162 sys_setsockopt(struct lwp *l, const struct sys_setsockopt_args *uap, 1163 register_t *retval) 1164 { 1165 /* { 1166 syscallarg(int) s; 1167 syscallarg(int) level; 1168 syscallarg(int) name; 1169 syscallarg(const void *) val; 1170 syscallarg(unsigned int) valsize; 1171 } */ 1172 struct sockopt sopt; 1173 struct socket *so; 1174 file_t *fp; 1175 int error; 1176 unsigned int len; 1177 1178 len = SCARG(uap, valsize); 1179 if (len > 0 && SCARG(uap, val) == NULL) 1180 return EINVAL; 1181 1182 if (len > MCLBYTES) 1183 return EINVAL; 1184 1185 if ((error = fd_getsock1(SCARG(uap, s), &so, &fp)) != 0) 1186 return (error); 1187 1188 sockopt_init(&sopt, SCARG(uap, level), SCARG(uap, name), len); 1189 1190 if (len > 0) { 1191 error = copyin(SCARG(uap, val), sopt.sopt_data, len); 1192 if (error) 1193 goto out; 1194 } 1195 1196 error = sosetopt(so, &sopt); 1197 if (so->so_options & SO_NOSIGPIPE) 1198 atomic_or_uint(&fp->f_flag, FNOSIGPIPE); 1199 else 1200 atomic_and_uint(&fp->f_flag, ~FNOSIGPIPE); 1201 1202 out: 1203 sockopt_destroy(&sopt); 1204 fd_putfile(SCARG(uap, s)); 1205 return error; 1206 } 1207 1208 static int 1209 getsockopt(struct lwp *l, const struct sys_getsockopt_args *uap, 1210 register_t *retval, bool copyarg) 1211 { 1212 struct sockopt sopt; 1213 struct socket *so; 1214 file_t *fp; 1215 unsigned int valsize, len; 1216 int error; 1217 1218 if (SCARG(uap, val) != NULL) { 1219 error = copyin(SCARG(uap, avalsize), &valsize, sizeof(valsize)); 1220 if (error) 1221 return error; 1222 } else 1223 valsize = 0; 1224 1225 if (valsize > MCLBYTES) 1226 return EINVAL; 1227 1228 if ((error = fd_getsock1(SCARG(uap, s), &so, &fp)) != 0) 1229 return error; 1230 1231 sockopt_init(&sopt, SCARG(uap, level), SCARG(uap, name), valsize); 1232 if (copyarg && valsize > 0) { 1233 error = copyin(SCARG(uap, val), sopt.sopt_data, valsize); 1234 if (error) 1235 goto out; 1236 } 1237 1238 if (fp->f_flag & FNOSIGPIPE) 1239 so->so_options |= SO_NOSIGPIPE; 1240 else 1241 so->so_options &= ~SO_NOSIGPIPE; 1242 1243 error = sogetopt(so, &sopt); 1244 if (error || valsize == 0) 1245 goto out; 1246 1247 len = uimin(valsize, sopt.sopt_retsize); 1248 error = copyout(sopt.sopt_data, SCARG(uap, val), len); 1249 if (error) 1250 goto out; 1251 1252 error = copyout(&len, SCARG(uap, avalsize), sizeof(len)); 1253 out: 1254 sockopt_destroy(&sopt); 1255 fd_putfile(SCARG(uap, s)); 1256 return error; 1257 } 1258 1259 int 1260 sys_getsockopt(struct lwp *l, const struct sys_getsockopt_args *uap, 1261 register_t *retval) 1262 { 1263 /* { 1264 syscallarg(int) s; 1265 syscallarg(int) level; 1266 syscallarg(int) name; 1267 syscallarg(void *) val; 1268 syscallarg(unsigned int *) avalsize; 1269 } */ 1270 return getsockopt(l, uap, retval, false); 1271 } 1272 1273 int 1274 sys_getsockopt2(struct lwp *l, const struct sys_getsockopt2_args *uap, 1275 register_t *retval) 1276 { 1277 /* { 1278 syscallarg(int) s; 1279 syscallarg(int) level; 1280 syscallarg(int) name; 1281 syscallarg(void *) val; 1282 syscallarg(unsigned int *) avalsize; 1283 } */ 1284 return getsockopt(l, (const struct sys_getsockopt_args *) uap, retval, true); 1285 } 1286 1287 #ifdef PIPE_SOCKETPAIR 1288 1289 int 1290 pipe1(struct lwp *l, int *fildes, int flags) 1291 { 1292 file_t *rf, *wf; 1293 struct socket *rso, *wso; 1294 int fd, error; 1295 proc_t *p; 1296 1297 if (flags & ~(O_CLOEXEC|O_NONBLOCK|O_NOSIGPIPE)) 1298 return EINVAL; 1299 p = curproc; 1300 if ((error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, l, NULL)) != 0) 1301 return error; 1302 if ((error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, l, rso)) != 0) 1303 goto free1; 1304 /* remember this socket pair implements a pipe */ 1305 wso->so_state |= SS_ISAPIPE; 1306 rso->so_state |= SS_ISAPIPE; 1307 if ((error = fd_allocfile(&rf, &fd)) != 0) 1308 goto free2; 1309 fildes[0] = fd; 1310 rf->f_flag = FREAD | flags; 1311 rf->f_type = DTYPE_SOCKET; 1312 rf->f_ops = &socketops; 1313 rf->f_socket = rso; 1314 if ((error = fd_allocfile(&wf, &fd)) != 0) 1315 goto free3; 1316 wf->f_flag = FWRITE | flags; 1317 wf->f_type = DTYPE_SOCKET; 1318 wf->f_ops = &socketops; 1319 wf->f_socket = wso; 1320 fildes[1] = fd; 1321 solock(wso); 1322 error = unp_connect2(wso, rso); 1323 sounlock(wso); 1324 if (error != 0) 1325 goto free4; 1326 fd_affix(p, wf, fildes[1]); 1327 fd_affix(p, rf, fildes[0]); 1328 return (0); 1329 free4: 1330 fd_abort(p, wf, fildes[1]); 1331 free3: 1332 fd_abort(p, rf, fildes[0]); 1333 free2: 1334 (void)soclose(wso); 1335 free1: 1336 (void)soclose(rso); 1337 return error; 1338 } 1339 #endif /* PIPE_SOCKETPAIR */ 1340 1341 /* 1342 * Get peer socket name. 1343 */ 1344 int 1345 do_sys_getpeername(int fd, struct sockaddr *nam) 1346 { 1347 struct socket *so; 1348 int error; 1349 1350 if ((error = fd_getsock(fd, &so)) != 0) 1351 return error; 1352 1353 solock(so); 1354 if ((so->so_state & SS_ISCONNECTED) == 0) 1355 error = ENOTCONN; 1356 else { 1357 error = (*so->so_proto->pr_usrreqs->pr_peeraddr)(so, nam); 1358 } 1359 sounlock(so); 1360 fd_putfile(fd); 1361 return error; 1362 } 1363 1364 /* 1365 * Get local socket name. 1366 */ 1367 int 1368 do_sys_getsockname(int fd, struct sockaddr *nam) 1369 { 1370 struct socket *so; 1371 int error; 1372 1373 if ((error = fd_getsock(fd, &so)) != 0) 1374 return error; 1375 1376 solock(so); 1377 error = (*so->so_proto->pr_usrreqs->pr_sockaddr)(so, nam); 1378 sounlock(so); 1379 fd_putfile(fd); 1380 return error; 1381 } 1382 1383 int 1384 copyout_sockname_sb(struct sockaddr *asa, unsigned int *alen, int flags, 1385 struct sockaddr_big *addr) 1386 { 1387 unsigned int len; 1388 int error; 1389 1390 if (asa == NULL) 1391 /* Assume application not interested */ 1392 return 0; 1393 1394 if (flags & MSG_LENUSRSPACE) { 1395 error = copyin(alen, &len, sizeof(len)); 1396 if (error) 1397 return error; 1398 } else 1399 len = *alen; 1400 1401 if (addr == NULL) { 1402 len = 0; 1403 error = 0; 1404 } else { 1405 if (len > addr->sb_len) 1406 len = addr->sb_len; 1407 /* XXX addr isn't an mbuf... */ 1408 ktrkuser(mbuftypes[MT_SONAME], addr, len); 1409 error = copyout(addr, asa, len); 1410 } 1411 1412 if (error == 0) { 1413 if (flags & MSG_LENUSRSPACE) 1414 error = copyout(&len, alen, sizeof(len)); 1415 else 1416 *alen = len; 1417 } 1418 1419 return error; 1420 } 1421 1422 int 1423 copyout_sockname(struct sockaddr *asa, unsigned int *alen, int flags, 1424 struct mbuf *addr) 1425 { 1426 int len; 1427 int error; 1428 1429 if (asa == NULL) 1430 /* Assume application not interested */ 1431 return 0; 1432 1433 if (flags & MSG_LENUSRSPACE) { 1434 error = copyin(alen, &len, sizeof(len)); 1435 if (error) 1436 return error; 1437 } else 1438 len = *alen; 1439 if (len < 0) 1440 return EINVAL; 1441 1442 if (addr == NULL) { 1443 len = 0; 1444 error = 0; 1445 } else { 1446 if (len > addr->m_len) 1447 len = addr->m_len; 1448 /* Maybe this ought to copy a chain ? */ 1449 ktrkuser(mbuftypes[MT_SONAME], mtod(addr, void *), len); 1450 error = copyout(mtod(addr, void *), asa, len); 1451 } 1452 1453 if (error == 0) { 1454 if (flags & MSG_LENUSRSPACE) 1455 error = copyout(&len, alen, sizeof(len)); 1456 else 1457 *alen = len; 1458 } 1459 1460 return error; 1461 } 1462 1463 /* 1464 * Get socket name. 1465 */ 1466 int 1467 sys_getsockname(struct lwp *l, const struct sys_getsockname_args *uap, 1468 register_t *retval) 1469 { 1470 /* { 1471 syscallarg(int) fdes; 1472 syscallarg(struct sockaddr *) asa; 1473 syscallarg(unsigned int *) alen; 1474 } */ 1475 struct sockaddr_big sbig; 1476 int error; 1477 1478 sbig.sb_len = UCHAR_MAX; 1479 error = do_sys_getsockname(SCARG(uap, fdes), (struct sockaddr *)&sbig); 1480 if (error != 0) 1481 return error; 1482 1483 error = copyout_sockname_sb(SCARG(uap, asa), SCARG(uap, alen), 1484 MSG_LENUSRSPACE, &sbig); 1485 return error; 1486 } 1487 1488 /* 1489 * Get name of peer for connected socket. 1490 */ 1491 int 1492 sys_getpeername(struct lwp *l, const struct sys_getpeername_args *uap, 1493 register_t *retval) 1494 { 1495 /* { 1496 syscallarg(int) fdes; 1497 syscallarg(struct sockaddr *) asa; 1498 syscallarg(unsigned int *) alen; 1499 } */ 1500 struct sockaddr_big sbig; 1501 int error; 1502 1503 sbig.sb_len = UCHAR_MAX; 1504 error = do_sys_getpeername(SCARG(uap, fdes), (struct sockaddr *)&sbig); 1505 if (error != 0) 1506 return error; 1507 1508 error = copyout_sockname_sb(SCARG(uap, asa), SCARG(uap, alen), 1509 MSG_LENUSRSPACE, &sbig); 1510 return error; 1511 } 1512 1513 static int 1514 sockargs_sb(struct sockaddr_big *sb, const void *name, socklen_t buflen) 1515 { 1516 int error; 1517 1518 /* 1519 * We can't allow socket names > UCHAR_MAX in length, since that 1520 * will overflow sb_len. Further no reasonable buflen is <= 1521 * offsetof(sockaddr_big, sb_data) since it shall be at least 1522 * the size of the preamble sb_len and sb_family members. 1523 */ 1524 if (buflen > UCHAR_MAX || 1525 buflen <= offsetof(struct sockaddr_big, sb_data)) 1526 return EINVAL; 1527 1528 error = copyin(name, (void *)sb, buflen); 1529 if (error) 1530 return error; 1531 1532 ktrkuser(mbuftypes[MT_SONAME], sb, buflen); 1533 #if BYTE_ORDER != BIG_ENDIAN 1534 /* 1535 * 4.3BSD compat thing - need to stay, since bind(2), 1536 * connect(2), sendto(2) were not versioned for COMPAT_43. 1537 */ 1538 if (sb->sb_family == 0 && sb->sb_len < AF_MAX) 1539 sb->sb_family = sb->sb_len; 1540 #endif 1541 sb->sb_len = buflen; 1542 return 0; 1543 } 1544 1545 /* 1546 * XXX In a perfect world, we wouldn't pass around socket control 1547 * XXX arguments in mbufs, and this could go away. 1548 */ 1549 int 1550 sockargs(struct mbuf **mp, const void *bf, size_t buflen, enum uio_seg seg, 1551 int type) 1552 { 1553 struct mbuf *m; 1554 int error; 1555 1556 /* 1557 * We can't allow socket names > UCHAR_MAX in length, since that 1558 * will overflow sa_len. Control data more than a page size in 1559 * length is just too much. 1560 */ 1561 if (buflen > (type == MT_SONAME ? UCHAR_MAX : PAGE_SIZE)) 1562 return EINVAL; 1563 1564 /* 1565 * length must greater than sizeof(sa_family) + sizeof(sa_len) 1566 */ 1567 if (type == MT_SONAME && buflen <= 2) 1568 return EINVAL; 1569 1570 /* Allocate an mbuf to hold the arguments. */ 1571 m = m_get(M_WAIT, type); 1572 /* can't claim. don't who to assign it to. */ 1573 if (buflen > MLEN) { 1574 /* 1575 * Won't fit into a regular mbuf, so we allocate just 1576 * enough external storage to hold the argument. 1577 */ 1578 MEXTMALLOC(m, buflen, M_WAITOK); 1579 } 1580 m->m_len = buflen; 1581 if (seg == UIO_USERSPACE) { 1582 error = copyin(bf, mtod(m, void *), buflen); 1583 if (error) { 1584 (void)m_free(m); 1585 return error; 1586 } 1587 } else { 1588 memcpy(mtod(m, void *), bf, buflen); 1589 } 1590 *mp = m; 1591 switch (type) { 1592 case MT_SONAME: 1593 ktrkuser(mbuftypes[type], mtod(m, void *), buflen); 1594 1595 struct sockaddr *sa = mtod(m, struct sockaddr *); 1596 #if BYTE_ORDER != BIG_ENDIAN 1597 /* 1598 * 4.3BSD compat thing - need to stay, since bind(2), 1599 * connect(2), sendto(2) were not versioned for COMPAT_43. 1600 */ 1601 if (sa->sa_family == 0 && sa->sa_len < AF_MAX) 1602 sa->sa_family = sa->sa_len; 1603 #endif 1604 sa->sa_len = buflen; 1605 return 0; 1606 case MT_CONTROL: 1607 if (!KTRPOINT(curproc, KTR_USER)) 1608 return 0; 1609 1610 struct msghdr mhdr; 1611 mhdr.msg_control = mtod(m, void *); 1612 mhdr.msg_controllen = buflen; 1613 for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mhdr); cmsg; 1614 cmsg = CMSG_NXTHDR(&mhdr, cmsg)) { 1615 ktrkuser(mbuftypes[type], cmsg, cmsg->cmsg_len); 1616 } 1617 return 0; 1618 default: 1619 return EINVAL; 1620 } 1621 } 1622 1623 int 1624 do_sys_peeloff(struct socket *head, void *data) 1625 { 1626 #ifdef SCTP 1627 /*file_t *lfp = NULL;*/ 1628 file_t *nfp = NULL; 1629 int error; 1630 struct socket *so; 1631 int fd; 1632 uint32_t name; 1633 /*short fflag;*/ /* type must match fp->f_flag */ 1634 1635 name = *(uint32_t *) data; 1636 error = sctp_can_peel_off(head, name); 1637 if (error) { 1638 printf("peeloff failed\n"); 1639 return error; 1640 } 1641 /* 1642 * At this point we know we do have a assoc to pull 1643 * we proceed to get the fd setup. This may block 1644 * but that is ok. 1645 */ 1646 error = fd_allocfile(&nfp, &fd); 1647 if (error) { 1648 /* 1649 * Probably ran out of file descriptors. Put the 1650 * unaccepted connection back onto the queue and 1651 * do another wakeup so some other process might 1652 * have a chance at it. 1653 */ 1654 return error; 1655 } 1656 *(int *) data = fd; 1657 1658 so = sctp_get_peeloff(head, name, &error); 1659 if (so == NULL) { 1660 /* 1661 * Either someone else peeled it off OR 1662 * we can't get a socket. 1663 * close the new descriptor, assuming someone hasn't ripped it 1664 * out from under us. 1665 */ 1666 mutex_enter(&nfp->f_lock); 1667 nfp->f_count++; 1668 mutex_exit(&nfp->f_lock); 1669 fd_abort(curlwp->l_proc, nfp, fd); 1670 return error; 1671 } 1672 so->so_state &= ~SS_NOFDREF; 1673 so->so_state &= ~SS_ISCONNECTING; 1674 so->so_head = NULL; 1675 so->so_cred = kauth_cred_dup(head->so_cred); 1676 nfp->f_socket = so; 1677 nfp->f_flag = FREAD|FWRITE; 1678 nfp->f_ops = &socketops; 1679 nfp->f_type = DTYPE_SOCKET; 1680 1681 fd_affix(curlwp->l_proc, nfp, fd); 1682 1683 return error; 1684 #else 1685 return EOPNOTSUPP; 1686 #endif 1687 } 1688