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