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