1 /* $NetBSD: uipc_syscalls.c,v 1.181 2015/11/01 17:23:36 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.181 2015/11/01 17:23:36 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), retval); 509 } 510 511 int 512 sys_sendmsg(struct lwp *l, const struct sys_sendmsg_args *uap, 513 register_t *retval) 514 { 515 /* { 516 syscallarg(int) s; 517 syscallarg(const struct msghdr *) msg; 518 syscallarg(int) flags; 519 } */ 520 struct msghdr msg; 521 int error; 522 523 error = copyin(SCARG(uap, msg), &msg, sizeof(msg)); 524 if (error) 525 return (error); 526 527 msg.msg_flags = MSG_IOVUSRSPACE; 528 return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), retval); 529 } 530 531 static int 532 do_sys_sendmsg_so(struct lwp *l, int s, struct socket *so, file_t *fp, 533 struct msghdr *mp, int flags, register_t *retsize) 534 { 535 536 struct iovec aiov[UIO_SMALLIOV], *iov = aiov, *tiov, *ktriov = NULL; 537 struct sockaddr *sa = NULL; 538 struct mbuf *to, *control; 539 struct uio auio; 540 size_t len, iovsz; 541 int i, error; 542 543 ktrkuser("msghdr", mp, sizeof *mp); 544 545 /* If the caller passed us stuff in mbufs, we must free them. */ 546 to = (mp->msg_flags & MSG_NAMEMBUF) ? mp->msg_name : NULL; 547 control = (mp->msg_flags & MSG_CONTROLMBUF) ? mp->msg_control : NULL; 548 iovsz = mp->msg_iovlen * sizeof(struct iovec); 549 550 if (mp->msg_flags & MSG_IOVUSRSPACE) { 551 if ((unsigned int)mp->msg_iovlen > UIO_SMALLIOV) { 552 if ((unsigned int)mp->msg_iovlen > IOV_MAX) { 553 error = EMSGSIZE; 554 goto bad; 555 } 556 iov = kmem_alloc(iovsz, KM_SLEEP); 557 } 558 if (mp->msg_iovlen != 0) { 559 error = copyin(mp->msg_iov, iov, iovsz); 560 if (error) 561 goto bad; 562 } 563 auio.uio_iov = iov; 564 } else 565 auio.uio_iov = mp->msg_iov; 566 567 auio.uio_iovcnt = mp->msg_iovlen; 568 auio.uio_rw = UIO_WRITE; 569 auio.uio_offset = 0; /* XXX */ 570 auio.uio_resid = 0; 571 KASSERT(l == curlwp); 572 auio.uio_vmspace = l->l_proc->p_vmspace; 573 574 tiov = auio.uio_iov; 575 for (i = 0; i < auio.uio_iovcnt; i++, tiov++) { 576 /* 577 * Writes return ssize_t because -1 is returned on error. 578 * Therefore, we must restrict the length to SSIZE_MAX to 579 * avoid garbage return values. 580 */ 581 auio.uio_resid += tiov->iov_len; 582 if (tiov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) { 583 error = EINVAL; 584 goto bad; 585 } 586 } 587 588 if (mp->msg_name && to == NULL) { 589 error = sockargs(&to, mp->msg_name, mp->msg_namelen, 590 MT_SONAME); 591 if (error) 592 goto bad; 593 } 594 595 if (mp->msg_control) { 596 if (mp->msg_controllen < CMSG_ALIGN(sizeof(struct cmsghdr))) { 597 error = EINVAL; 598 goto bad; 599 } 600 if (control == NULL) { 601 error = sockargs(&control, mp->msg_control, 602 mp->msg_controllen, MT_CONTROL); 603 if (error) 604 goto bad; 605 } 606 } 607 608 if (ktrpoint(KTR_GENIO) && iovsz > 0) { 609 ktriov = kmem_alloc(iovsz, KM_SLEEP); 610 memcpy(ktriov, auio.uio_iov, iovsz); 611 } 612 613 if (mp->msg_name) 614 MCLAIM(to, so->so_mowner); 615 if (mp->msg_control) 616 MCLAIM(control, so->so_mowner); 617 618 if (to) { 619 sa = mtod(to, struct sockaddr *); 620 } 621 622 len = auio.uio_resid; 623 error = (*so->so_send)(so, sa, &auio, NULL, control, flags, l); 624 /* Protocol is responsible for freeing 'control' */ 625 control = NULL; 626 627 if (error) { 628 if (auio.uio_resid != len && (error == ERESTART || 629 error == EINTR || error == EWOULDBLOCK)) 630 error = 0; 631 if (error == EPIPE && (fp->f_flag & FNOSIGPIPE) == 0 && 632 (flags & MSG_NOSIGNAL) == 0) { 633 mutex_enter(proc_lock); 634 psignal(l->l_proc, SIGPIPE); 635 mutex_exit(proc_lock); 636 } 637 } 638 if (error == 0) 639 *retsize = len - auio.uio_resid; 640 641 bad: 642 if (ktriov != NULL) { 643 ktrgeniov(s, UIO_WRITE, ktriov, *retsize, error); 644 kmem_free(ktriov, iovsz); 645 } 646 647 if (iov != aiov) 648 kmem_free(iov, iovsz); 649 if (to) 650 m_freem(to); 651 if (control) 652 m_freem(control); 653 654 return error; 655 } 656 657 int 658 do_sys_sendmsg(struct lwp *l, int s, struct msghdr *mp, int flags, 659 register_t *retsize) 660 { 661 int error; 662 struct socket *so; 663 file_t *fp; 664 665 if ((error = fd_getsock1(s, &so, &fp)) != 0) { 666 /* We have to free msg_name and msg_control ourselves */ 667 if (mp->msg_flags & MSG_NAMEMBUF) 668 m_freem(mp->msg_name); 669 if (mp->msg_flags & MSG_CONTROLMBUF) 670 m_freem(mp->msg_control); 671 return error; 672 } 673 error = do_sys_sendmsg_so(l, s, so, fp, mp, flags, retsize); 674 /* msg_name and msg_control freed */ 675 fd_putfile(s); 676 return error; 677 } 678 679 int 680 sys_recvfrom(struct lwp *l, const struct sys_recvfrom_args *uap, 681 register_t *retval) 682 { 683 /* { 684 syscallarg(int) s; 685 syscallarg(void *) buf; 686 syscallarg(size_t) len; 687 syscallarg(int) flags; 688 syscallarg(struct sockaddr *) from; 689 syscallarg(unsigned int *) fromlenaddr; 690 } */ 691 struct msghdr msg; 692 struct iovec aiov; 693 int error; 694 struct mbuf *from; 695 696 msg.msg_name = NULL; 697 msg.msg_iov = &aiov; 698 msg.msg_iovlen = 1; 699 aiov.iov_base = SCARG(uap, buf); 700 aiov.iov_len = SCARG(uap, len); 701 msg.msg_control = NULL; 702 msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS; 703 704 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, NULL, retval); 705 if (error != 0) 706 return error; 707 708 error = copyout_sockname(SCARG(uap, from), SCARG(uap, fromlenaddr), 709 MSG_LENUSRSPACE, from); 710 if (from != NULL) 711 m_free(from); 712 return error; 713 } 714 715 int 716 sys_recvmsg(struct lwp *l, const struct sys_recvmsg_args *uap, 717 register_t *retval) 718 { 719 /* { 720 syscallarg(int) s; 721 syscallarg(struct msghdr *) msg; 722 syscallarg(int) flags; 723 } */ 724 struct msghdr msg; 725 int error; 726 struct mbuf *from, *control; 727 728 error = copyin(SCARG(uap, msg), &msg, sizeof(msg)); 729 if (error) 730 return error; 731 732 msg.msg_flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE; 733 734 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, 735 msg.msg_control != NULL ? &control : NULL, retval); 736 if (error != 0) 737 return error; 738 739 if (msg.msg_control != NULL) 740 error = copyout_msg_control(l, &msg, control); 741 742 if (error == 0) 743 error = copyout_sockname(msg.msg_name, &msg.msg_namelen, 0, 744 from); 745 if (from != NULL) 746 m_free(from); 747 if (error == 0) { 748 ktrkuser("msghdr", &msg, sizeof msg); 749 error = copyout(&msg, SCARG(uap, msg), sizeof(msg)); 750 } 751 752 return error; 753 } 754 755 int 756 sys_sendmmsg(struct lwp *l, const struct sys_sendmmsg_args *uap, 757 register_t *retval) 758 { 759 /* { 760 syscallarg(int) s; 761 syscallarg(struct mmsghdr *) mmsg; 762 syscallarg(unsigned int) vlen; 763 syscallarg(unsigned int) flags; 764 } */ 765 struct mmsghdr mmsg; 766 struct socket *so; 767 file_t *fp; 768 struct msghdr *msg = &mmsg.msg_hdr; 769 int error, s; 770 unsigned int vlen, flags, dg; 771 772 s = SCARG(uap, s); 773 if ((error = fd_getsock1(s, &so, &fp)) != 0) 774 return error; 775 776 vlen = SCARG(uap, vlen); 777 if (vlen > 1024) 778 vlen = 1024; 779 780 flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE; 781 782 for (dg = 0; dg < vlen;) { 783 error = copyin(SCARG(uap, mmsg) + dg, &mmsg, sizeof(mmsg)); 784 if (error) 785 break; 786 787 msg->msg_flags = flags; 788 789 error = do_sys_sendmsg_so(l, s, so, fp, msg, flags, retval); 790 if (error) 791 break; 792 793 ktrkuser("msghdr", msg, sizeof *msg); 794 mmsg.msg_len = *retval; 795 error = copyout(&mmsg, SCARG(uap, mmsg) + dg, sizeof(mmsg)); 796 if (error) 797 break; 798 dg++; 799 800 } 801 802 *retval = dg; 803 if (error) 804 so->so_error = error; 805 806 fd_putfile(s); 807 808 /* 809 * If we succeeded at least once, return 0, hopefully so->so_error 810 * will catch it next time. 811 */ 812 if (dg) 813 return 0; 814 return error; 815 } 816 817 /* 818 * Adjust for a truncated SCM_RIGHTS control message. 819 * This means closing any file descriptors that aren't present 820 * in the returned buffer. 821 * m is the mbuf holding the (already externalized) SCM_RIGHTS message. 822 */ 823 static void 824 free_rights(struct mbuf *m) 825 { 826 struct cmsghdr *cm; 827 int *fdv; 828 unsigned int nfds, i; 829 830 KASSERT(sizeof(*cm) <= m->m_len); 831 cm = mtod(m, struct cmsghdr *); 832 833 KASSERT(CMSG_ALIGN(sizeof(*cm)) <= cm->cmsg_len); 834 KASSERT(cm->cmsg_len <= m->m_len); 835 nfds = (cm->cmsg_len - CMSG_ALIGN(sizeof(*cm))) / sizeof(int); 836 fdv = (int *)CMSG_DATA(cm); 837 838 for (i = 0; i < nfds; i++) 839 if (fd_getfile(fdv[i]) != NULL) 840 (void)fd_close(fdv[i]); 841 } 842 843 void 844 free_control_mbuf(struct lwp *l, struct mbuf *control, struct mbuf *uncopied) 845 { 846 struct mbuf *next; 847 struct cmsghdr *cmsg; 848 bool do_free_rights = false; 849 850 while (control != NULL) { 851 cmsg = mtod(control, struct cmsghdr *); 852 if (control == uncopied) 853 do_free_rights = true; 854 if (do_free_rights && cmsg->cmsg_level == SOL_SOCKET 855 && cmsg->cmsg_type == SCM_RIGHTS) 856 free_rights(control); 857 next = control->m_next; 858 m_free(control); 859 control = next; 860 } 861 } 862 863 /* Copy socket control/CMSG data to user buffer, frees the mbuf */ 864 int 865 copyout_msg_control(struct lwp *l, struct msghdr *mp, struct mbuf *control) 866 { 867 int i, len, error = 0; 868 struct cmsghdr *cmsg; 869 struct mbuf *m; 870 char *q; 871 872 len = mp->msg_controllen; 873 if (len <= 0 || control == 0) { 874 mp->msg_controllen = 0; 875 free_control_mbuf(l, control, control); 876 return 0; 877 } 878 879 q = (char *)mp->msg_control; 880 881 for (m = control; m != NULL; ) { 882 cmsg = mtod(m, struct cmsghdr *); 883 i = m->m_len; 884 if (len < i) { 885 mp->msg_flags |= MSG_CTRUNC; 886 if (cmsg->cmsg_level == SOL_SOCKET 887 && cmsg->cmsg_type == SCM_RIGHTS) 888 /* Do not truncate me ... */ 889 break; 890 i = len; 891 } 892 error = copyout(mtod(m, void *), q, i); 893 ktrkuser("msgcontrol", mtod(m, void *), i); 894 if (error != 0) { 895 /* We must free all the SCM_RIGHTS */ 896 m = control; 897 break; 898 } 899 m = m->m_next; 900 if (m) 901 i = ALIGN(i); 902 q += i; 903 len -= i; 904 if (len <= 0) 905 break; 906 } 907 908 free_control_mbuf(l, control, m); 909 910 mp->msg_controllen = q - (char *)mp->msg_control; 911 return error; 912 } 913 914 static int 915 do_sys_recvmsg_so(struct lwp *l, int s, struct socket *so, struct msghdr *mp, 916 struct mbuf **from, struct mbuf **control, register_t *retsize) 917 { 918 struct iovec aiov[UIO_SMALLIOV], *iov = aiov, *tiov, *ktriov = NULL; 919 struct uio auio; 920 size_t len, iovsz; 921 int i, error; 922 923 ktrkuser("msghdr", mp, sizeof *mp); 924 925 *from = NULL; 926 if (control != NULL) 927 *control = NULL; 928 929 iovsz = mp->msg_iovlen * sizeof(struct iovec); 930 931 if (mp->msg_flags & MSG_IOVUSRSPACE) { 932 if ((unsigned int)mp->msg_iovlen > UIO_SMALLIOV) { 933 if ((unsigned int)mp->msg_iovlen > IOV_MAX) { 934 error = EMSGSIZE; 935 goto out; 936 } 937 iov = kmem_alloc(iovsz, KM_SLEEP); 938 } 939 if (mp->msg_iovlen != 0) { 940 error = copyin(mp->msg_iov, iov, iovsz); 941 if (error) 942 goto out; 943 } 944 auio.uio_iov = iov; 945 } else 946 auio.uio_iov = mp->msg_iov; 947 auio.uio_iovcnt = mp->msg_iovlen; 948 auio.uio_rw = UIO_READ; 949 auio.uio_offset = 0; /* XXX */ 950 auio.uio_resid = 0; 951 KASSERT(l == curlwp); 952 auio.uio_vmspace = l->l_proc->p_vmspace; 953 954 tiov = auio.uio_iov; 955 for (i = 0; i < auio.uio_iovcnt; i++, tiov++) { 956 /* 957 * Reads return ssize_t because -1 is returned on error. 958 * Therefore we must restrict the length to SSIZE_MAX to 959 * avoid garbage return values. 960 */ 961 auio.uio_resid += tiov->iov_len; 962 if (tiov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) { 963 error = EINVAL; 964 goto out; 965 } 966 } 967 968 if (ktrpoint(KTR_GENIO) && iovsz > 0) { 969 ktriov = kmem_alloc(iovsz, KM_SLEEP); 970 memcpy(ktriov, auio.uio_iov, iovsz); 971 } 972 973 len = auio.uio_resid; 974 mp->msg_flags &= MSG_USERFLAGS; 975 error = (*so->so_receive)(so, from, &auio, NULL, control, 976 &mp->msg_flags); 977 len -= auio.uio_resid; 978 *retsize = len; 979 if (error != 0 && len != 0 980 && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) 981 /* Some data transferred */ 982 error = 0; 983 984 if (ktriov != NULL) { 985 ktrgeniov(s, UIO_READ, ktriov, len, error); 986 kmem_free(ktriov, iovsz); 987 } 988 989 if (error != 0) { 990 m_freem(*from); 991 *from = NULL; 992 if (control != NULL) { 993 free_control_mbuf(l, *control, *control); 994 *control = NULL; 995 } 996 } 997 out: 998 if (iov != aiov) 999 kmem_free(iov, iovsz); 1000 return error; 1001 } 1002 1003 1004 int 1005 do_sys_recvmsg(struct lwp *l, int s, struct msghdr *mp, struct mbuf **from, 1006 struct mbuf **control, register_t *retsize) 1007 { 1008 int error; 1009 struct socket *so; 1010 1011 if ((error = fd_getsock(s, &so)) != 0) 1012 return error; 1013 error = do_sys_recvmsg_so(l, s, so, mp, from, control, retsize); 1014 fd_putfile(s); 1015 return error; 1016 } 1017 1018 int 1019 sys_recvmmsg(struct lwp *l, const struct sys_recvmmsg_args *uap, 1020 register_t *retval) 1021 { 1022 /* { 1023 syscallarg(int) s; 1024 syscallarg(struct mmsghdr *) mmsg; 1025 syscallarg(unsigned int) vlen; 1026 syscallarg(unsigned int) flags; 1027 syscallarg(struct timespec *) timeout; 1028 } */ 1029 struct mmsghdr mmsg; 1030 struct socket *so; 1031 struct msghdr *msg = &mmsg.msg_hdr; 1032 int error, s; 1033 struct mbuf *from, *control; 1034 struct timespec ts, now; 1035 unsigned int vlen, flags, dg; 1036 1037 if (SCARG(uap, timeout)) { 1038 if ((error = copyin(SCARG(uap, timeout), &ts, sizeof(ts))) != 0) 1039 return error; 1040 getnanotime(&now); 1041 timespecadd(&now, &ts, &ts); 1042 } 1043 1044 s = SCARG(uap, s); 1045 if ((error = fd_getsock(s, &so)) != 0) 1046 return error; 1047 1048 vlen = SCARG(uap, vlen); 1049 if (vlen > 1024) 1050 vlen = 1024; 1051 1052 from = NULL; 1053 flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE; 1054 1055 for (dg = 0; dg < vlen;) { 1056 error = copyin(SCARG(uap, mmsg) + dg, &mmsg, sizeof(mmsg)); 1057 if (error) 1058 break; 1059 1060 msg->msg_flags = flags & ~MSG_WAITFORONE; 1061 1062 if (from != NULL) { 1063 m_free(from); 1064 from = NULL; 1065 } 1066 1067 error = do_sys_recvmsg_so(l, s, so, msg, &from, 1068 msg->msg_control != NULL ? &control : NULL, retval); 1069 if (error) { 1070 if (error == EAGAIN && dg > 0) 1071 error = 0; 1072 break; 1073 } 1074 1075 if (msg->msg_control != NULL) 1076 error = copyout_msg_control(l, msg, control); 1077 if (error) 1078 break; 1079 1080 error = copyout_sockname(msg->msg_name, &msg->msg_namelen, 0, 1081 from); 1082 if (error) 1083 break; 1084 1085 ktrkuser("msghdr", msg, sizeof *msg); 1086 mmsg.msg_len = *retval; 1087 1088 error = copyout(&mmsg, SCARG(uap, mmsg) + dg, sizeof(mmsg)); 1089 if (error) 1090 break; 1091 1092 dg++; 1093 if (msg->msg_flags & MSG_OOB) 1094 break; 1095 1096 if (SCARG(uap, timeout)) { 1097 getnanotime(&now); 1098 timespecsub(&now, &ts, &now); 1099 if (now.tv_sec > 0) 1100 break; 1101 } 1102 1103 if (flags & MSG_WAITFORONE) 1104 flags |= MSG_DONTWAIT; 1105 1106 } 1107 1108 if (from != NULL) 1109 m_free(from); 1110 1111 *retval = dg; 1112 if (error) 1113 so->so_error = error; 1114 1115 fd_putfile(s); 1116 1117 /* 1118 * If we succeeded at least once, return 0, hopefully so->so_error 1119 * will catch it next time. 1120 */ 1121 if (dg) 1122 return 0; 1123 1124 return error; 1125 } 1126 1127 int 1128 sys_shutdown(struct lwp *l, const struct sys_shutdown_args *uap, 1129 register_t *retval) 1130 { 1131 /* { 1132 syscallarg(int) s; 1133 syscallarg(int) how; 1134 } */ 1135 struct socket *so; 1136 int error; 1137 1138 if ((error = fd_getsock(SCARG(uap, s), &so)) != 0) 1139 return error; 1140 solock(so); 1141 error = soshutdown(so, SCARG(uap, how)); 1142 sounlock(so); 1143 fd_putfile(SCARG(uap, s)); 1144 return error; 1145 } 1146 1147 int 1148 sys_setsockopt(struct lwp *l, const struct sys_setsockopt_args *uap, 1149 register_t *retval) 1150 { 1151 /* { 1152 syscallarg(int) s; 1153 syscallarg(int) level; 1154 syscallarg(int) name; 1155 syscallarg(const void *) val; 1156 syscallarg(unsigned int) valsize; 1157 } */ 1158 struct sockopt sopt; 1159 struct socket *so; 1160 file_t *fp; 1161 int error; 1162 unsigned int len; 1163 1164 len = SCARG(uap, valsize); 1165 if (len > 0 && SCARG(uap, val) == NULL) 1166 return EINVAL; 1167 1168 if (len > MCLBYTES) 1169 return EINVAL; 1170 1171 if ((error = fd_getsock1(SCARG(uap, s), &so, &fp)) != 0) 1172 return (error); 1173 1174 sockopt_init(&sopt, SCARG(uap, level), SCARG(uap, name), len); 1175 1176 if (len > 0) { 1177 error = copyin(SCARG(uap, val), sopt.sopt_data, len); 1178 if (error) 1179 goto out; 1180 } 1181 1182 error = sosetopt(so, &sopt); 1183 if (so->so_options & SO_NOSIGPIPE) 1184 atomic_or_uint(&fp->f_flag, FNOSIGPIPE); 1185 else 1186 atomic_and_uint(&fp->f_flag, ~FNOSIGPIPE); 1187 1188 out: 1189 sockopt_destroy(&sopt); 1190 fd_putfile(SCARG(uap, s)); 1191 return error; 1192 } 1193 1194 int 1195 sys_getsockopt(struct lwp *l, const struct sys_getsockopt_args *uap, 1196 register_t *retval) 1197 { 1198 /* { 1199 syscallarg(int) s; 1200 syscallarg(int) level; 1201 syscallarg(int) name; 1202 syscallarg(void *) val; 1203 syscallarg(unsigned int *) avalsize; 1204 } */ 1205 struct sockopt sopt; 1206 struct socket *so; 1207 file_t *fp; 1208 unsigned int valsize, len; 1209 int error; 1210 1211 if (SCARG(uap, val) != NULL) { 1212 error = copyin(SCARG(uap, avalsize), &valsize, sizeof(valsize)); 1213 if (error) 1214 return error; 1215 } else 1216 valsize = 0; 1217 1218 if ((error = fd_getsock1(SCARG(uap, s), &so, &fp)) != 0) 1219 return (error); 1220 1221 sockopt_init(&sopt, SCARG(uap, level), SCARG(uap, name), 0); 1222 1223 if (fp->f_flag & FNOSIGPIPE) 1224 so->so_options |= SO_NOSIGPIPE; 1225 else 1226 so->so_options &= ~SO_NOSIGPIPE; 1227 error = sogetopt(so, &sopt); 1228 if (error) 1229 goto out; 1230 1231 if (valsize > 0) { 1232 len = min(valsize, sopt.sopt_size); 1233 error = copyout(sopt.sopt_data, SCARG(uap, val), len); 1234 if (error) 1235 goto out; 1236 1237 error = copyout(&len, SCARG(uap, avalsize), sizeof(len)); 1238 if (error) 1239 goto out; 1240 } 1241 1242 out: 1243 sockopt_destroy(&sopt); 1244 fd_putfile(SCARG(uap, s)); 1245 return error; 1246 } 1247 1248 #ifdef PIPE_SOCKETPAIR 1249 1250 int 1251 pipe1(struct lwp *l, register_t *retval, int flags) 1252 { 1253 file_t *rf, *wf; 1254 struct socket *rso, *wso; 1255 int fd, error; 1256 proc_t *p; 1257 1258 if (flags & ~(O_CLOEXEC|O_NONBLOCK|O_NOSIGPIPE)) 1259 return EINVAL; 1260 p = curproc; 1261 if ((error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, l, NULL)) != 0) 1262 return error; 1263 if ((error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, l, rso)) != 0) 1264 goto free1; 1265 /* remember this socket pair implements a pipe */ 1266 wso->so_state |= SS_ISAPIPE; 1267 rso->so_state |= SS_ISAPIPE; 1268 if ((error = fd_allocfile(&rf, &fd)) != 0) 1269 goto free2; 1270 retval[0] = fd; 1271 rf->f_flag = FREAD | flags; 1272 rf->f_type = DTYPE_SOCKET; 1273 rf->f_ops = &socketops; 1274 rf->f_socket = rso; 1275 if ((error = fd_allocfile(&wf, &fd)) != 0) 1276 goto free3; 1277 wf->f_flag = FWRITE | flags; 1278 wf->f_type = DTYPE_SOCKET; 1279 wf->f_ops = &socketops; 1280 wf->f_socket = wso; 1281 retval[1] = fd; 1282 solock(wso); 1283 error = unp_connect2(wso, rso); 1284 sounlock(wso); 1285 if (error != 0) 1286 goto free4; 1287 fd_affix(p, wf, (int)retval[1]); 1288 fd_affix(p, rf, (int)retval[0]); 1289 return (0); 1290 free4: 1291 fd_abort(p, wf, (int)retval[1]); 1292 free3: 1293 fd_abort(p, rf, (int)retval[0]); 1294 free2: 1295 (void)soclose(wso); 1296 free1: 1297 (void)soclose(rso); 1298 return error; 1299 } 1300 #endif /* PIPE_SOCKETPAIR */ 1301 1302 /* 1303 * Get peer socket name. 1304 */ 1305 int 1306 do_sys_getpeername(int fd, struct sockaddr *nam) 1307 { 1308 struct socket *so; 1309 int error; 1310 1311 if ((error = fd_getsock(fd, &so)) != 0) 1312 return error; 1313 1314 solock(so); 1315 if ((so->so_state & SS_ISCONNECTED) == 0) 1316 error = ENOTCONN; 1317 else { 1318 error = (*so->so_proto->pr_usrreqs->pr_peeraddr)(so, nam); 1319 } 1320 sounlock(so); 1321 fd_putfile(fd); 1322 return error; 1323 } 1324 1325 /* 1326 * Get local socket name. 1327 */ 1328 int 1329 do_sys_getsockname(int fd, struct sockaddr *nam) 1330 { 1331 struct socket *so; 1332 int error; 1333 1334 if ((error = fd_getsock(fd, &so)) != 0) 1335 return error; 1336 1337 solock(so); 1338 error = (*so->so_proto->pr_usrreqs->pr_sockaddr)(so, nam); 1339 sounlock(so); 1340 fd_putfile(fd); 1341 return error; 1342 } 1343 1344 int 1345 copyout_sockname_sb(struct sockaddr *asa, unsigned int *alen, int flags, 1346 struct sockaddr_big *addr) 1347 { 1348 int len; 1349 int error; 1350 1351 if (asa == NULL) 1352 /* Assume application not interested */ 1353 return 0; 1354 1355 if (flags & MSG_LENUSRSPACE) { 1356 error = copyin(alen, &len, sizeof(len)); 1357 if (error) 1358 return error; 1359 } else 1360 len = *alen; 1361 if (len < 0) 1362 return EINVAL; 1363 1364 if (addr == NULL) { 1365 len = 0; 1366 error = 0; 1367 } else { 1368 if (len > addr->sb_len) 1369 len = addr->sb_len; 1370 /* XXX addr isn't an mbuf... */ 1371 ktrkuser(mbuftypes[MT_SONAME], addr, len); 1372 error = copyout(addr, asa, len); 1373 } 1374 1375 if (error == 0) { 1376 if (flags & MSG_LENUSRSPACE) 1377 error = copyout(&len, alen, sizeof(len)); 1378 else 1379 *alen = len; 1380 } 1381 1382 return error; 1383 } 1384 1385 int 1386 copyout_sockname(struct sockaddr *asa, unsigned int *alen, int flags, 1387 struct mbuf *addr) 1388 { 1389 int len; 1390 int error; 1391 1392 if (asa == NULL) 1393 /* Assume application not interested */ 1394 return 0; 1395 1396 if (flags & MSG_LENUSRSPACE) { 1397 error = copyin(alen, &len, sizeof(len)); 1398 if (error) 1399 return error; 1400 } else 1401 len = *alen; 1402 if (len < 0) 1403 return EINVAL; 1404 1405 if (addr == NULL) { 1406 len = 0; 1407 error = 0; 1408 } else { 1409 if (len > addr->m_len) 1410 len = addr->m_len; 1411 /* Maybe this ought to copy a chain ? */ 1412 ktrkuser(mbuftypes[MT_SONAME], mtod(addr, void *), len); 1413 error = copyout(mtod(addr, void *), asa, len); 1414 } 1415 1416 if (error == 0) { 1417 if (flags & MSG_LENUSRSPACE) 1418 error = copyout(&len, alen, sizeof(len)); 1419 else 1420 *alen = len; 1421 } 1422 1423 return error; 1424 } 1425 1426 /* 1427 * Get socket name. 1428 */ 1429 int 1430 sys_getsockname(struct lwp *l, const struct sys_getsockname_args *uap, 1431 register_t *retval) 1432 { 1433 /* { 1434 syscallarg(int) fdes; 1435 syscallarg(struct sockaddr *) asa; 1436 syscallarg(unsigned int *) alen; 1437 } */ 1438 struct sockaddr_big sbig; 1439 int error; 1440 1441 sbig.sb_len = UCHAR_MAX; 1442 error = do_sys_getsockname(SCARG(uap, fdes), (struct sockaddr *)&sbig); 1443 if (error != 0) 1444 return error; 1445 1446 error = copyout_sockname_sb(SCARG(uap, asa), SCARG(uap, alen), 1447 MSG_LENUSRSPACE, &sbig); 1448 return error; 1449 } 1450 1451 /* 1452 * Get name of peer for connected socket. 1453 */ 1454 int 1455 sys_getpeername(struct lwp *l, const struct sys_getpeername_args *uap, 1456 register_t *retval) 1457 { 1458 /* { 1459 syscallarg(int) fdes; 1460 syscallarg(struct sockaddr *) asa; 1461 syscallarg(unsigned int *) alen; 1462 } */ 1463 struct sockaddr_big sbig; 1464 int error; 1465 1466 sbig.sb_len = UCHAR_MAX; 1467 error = do_sys_getpeername(SCARG(uap, fdes), (struct sockaddr *)&sbig); 1468 if (error != 0) 1469 return error; 1470 1471 error = copyout_sockname_sb(SCARG(uap, asa), SCARG(uap, alen), 1472 MSG_LENUSRSPACE, &sbig); 1473 return error; 1474 } 1475 1476 static int 1477 sockargs_sb(struct sockaddr_big *sb, const void *name, socklen_t buflen) 1478 { 1479 int error; 1480 1481 /* 1482 * We can't allow socket names > UCHAR_MAX in length, since that 1483 * will overflow sb_len. Further no reasonable buflen is <= 1484 * offsetof(sockaddr_big, sb_data) since it shall be at least 1485 * the size of the preamble sb_len and sb_family members. 1486 */ 1487 if (buflen > UCHAR_MAX || 1488 buflen <= offsetof(struct sockaddr_big, sb_data)) 1489 return EINVAL; 1490 1491 error = copyin(name, (void *)sb, buflen); 1492 if (error) 1493 return error; 1494 1495 #if BYTE_ORDER != BIG_ENDIAN 1496 /* 1497 * 4.3BSD compat thing - need to stay, since bind(2), 1498 * connect(2), sendto(2) were not versioned for COMPAT_43. 1499 */ 1500 if (sb->sb_family == 0 && sb->sb_len < AF_MAX) 1501 sb->sb_family = sb->sb_len; 1502 #endif 1503 sb->sb_len = buflen; 1504 return 0; 1505 } 1506 1507 /* 1508 * XXX In a perfect world, we wouldn't pass around socket control 1509 * XXX arguments in mbufs, and this could go away. 1510 */ 1511 int 1512 sockargs(struct mbuf **mp, const void *bf, size_t buflen, int type) 1513 { 1514 struct sockaddr *sa; 1515 struct mbuf *m; 1516 int error; 1517 1518 /* 1519 * We can't allow socket names > UCHAR_MAX in length, since that 1520 * will overflow sa_len. Control data more than a page size in 1521 * length is just too much. 1522 */ 1523 if (buflen > (type == MT_SONAME ? UCHAR_MAX : PAGE_SIZE)) 1524 return EINVAL; 1525 1526 /* 1527 * length must greater than sizeof(sa_family) + sizeof(sa_len) 1528 */ 1529 if (type == MT_SONAME && buflen <= 2) 1530 return EINVAL; 1531 1532 /* Allocate an mbuf to hold the arguments. */ 1533 m = m_get(M_WAIT, type); 1534 /* can't claim. don't who to assign it to. */ 1535 if (buflen > MLEN) { 1536 /* 1537 * Won't fit into a regular mbuf, so we allocate just 1538 * enough external storage to hold the argument. 1539 */ 1540 MEXTMALLOC(m, buflen, M_WAITOK); 1541 } 1542 m->m_len = buflen; 1543 error = copyin(bf, mtod(m, void *), buflen); 1544 if (error) { 1545 (void)m_free(m); 1546 return error; 1547 } 1548 ktrkuser(mbuftypes[type], mtod(m, void *), buflen); 1549 *mp = m; 1550 if (type == MT_SONAME) { 1551 sa = mtod(m, struct sockaddr *); 1552 #if BYTE_ORDER != BIG_ENDIAN 1553 /* 1554 * 4.3BSD compat thing - need to stay, since bind(2), 1555 * connect(2), sendto(2) were not versioned for COMPAT_43. 1556 */ 1557 if (sa->sa_family == 0 && sa->sa_len < AF_MAX) 1558 sa->sa_family = sa->sa_len; 1559 #endif 1560 sa->sa_len = buflen; 1561 } 1562 return 0; 1563 } 1564