1 /* $NetBSD: uipc_syscalls.c,v 1.145 2011/07/15 14:50:19 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.145 2011/07/15 14:50:19 christos Exp $"); 65 66 #include "opt_pipe.h" 67 68 #include <sys/param.h> 69 #include <sys/systm.h> 70 #include <sys/filedesc.h> 71 #include <sys/proc.h> 72 #include <sys/file.h> 73 #include <sys/buf.h> 74 #include <sys/mbuf.h> 75 #include <sys/protosw.h> 76 #include <sys/socket.h> 77 #include <sys/socketvar.h> 78 #include <sys/signalvar.h> 79 #include <sys/un.h> 80 #include <sys/ktrace.h> 81 #include <sys/event.h> 82 #include <sys/kauth.h> 83 84 #include <sys/mount.h> 85 #include <sys/syscallargs.h> 86 87 #include <uvm/uvm_extern.h> 88 89 /* 90 * System call interface to the socket abstraction. 91 */ 92 extern const struct fileops socketops; 93 94 int 95 sys___socket30(struct lwp *l, const struct sys___socket30_args *uap, register_t *retval) 96 { 97 /* { 98 syscallarg(int) domain; 99 syscallarg(int) type; 100 syscallarg(int) protocol; 101 } */ 102 int fd, error; 103 104 error = fsocreate(SCARG(uap, domain), NULL, SCARG(uap, type), 105 SCARG(uap, protocol), l, &fd); 106 if (error == 0) 107 *retval = fd; 108 return error; 109 } 110 111 /* ARGSUSED */ 112 int 113 sys_bind(struct lwp *l, const struct sys_bind_args *uap, register_t *retval) 114 { 115 /* { 116 syscallarg(int) s; 117 syscallarg(const struct sockaddr *) name; 118 syscallarg(unsigned int) namelen; 119 } */ 120 struct mbuf *nam; 121 int error; 122 123 error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen), 124 MT_SONAME); 125 if (error) 126 return error; 127 128 return do_sys_bind(l, SCARG(uap, s), nam); 129 } 130 131 int 132 do_sys_bind(struct lwp *l, int fd, struct mbuf *nam) 133 { 134 struct socket *so; 135 int error; 136 137 if ((error = fd_getsock(fd, &so)) != 0) { 138 m_freem(nam); 139 return (error); 140 } 141 MCLAIM(nam, so->so_mowner); 142 error = sobind(so, nam, l); 143 m_freem(nam); 144 fd_putfile(fd); 145 return error; 146 } 147 148 /* ARGSUSED */ 149 int 150 sys_listen(struct lwp *l, const struct sys_listen_args *uap, register_t *retval) 151 { 152 /* { 153 syscallarg(int) s; 154 syscallarg(int) backlog; 155 } */ 156 struct socket *so; 157 int error; 158 159 if ((error = fd_getsock(SCARG(uap, s), &so)) != 0) 160 return (error); 161 error = solisten(so, SCARG(uap, backlog), l); 162 fd_putfile(SCARG(uap, s)); 163 return error; 164 } 165 166 int 167 do_sys_accept(struct lwp *l, int sock, struct mbuf **name, register_t *new_sock, 168 const sigset_t *mask, int flags, int clrflags) 169 { 170 file_t *fp, *fp2; 171 struct mbuf *nam; 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 nam = m_get(M_WAIT, MT_SONAME); 187 *new_sock = fd; 188 so = fp->f_data; 189 solock(so); 190 191 if (__predict_false(mask)) 192 sigsuspendsetup(l, mask); 193 194 if (!(so->so_proto->pr_flags & PR_LISTEN)) { 195 error = EOPNOTSUPP; 196 goto bad; 197 } 198 if ((so->so_options & SO_ACCEPTCONN) == 0) { 199 error = EINVAL; 200 goto bad; 201 } 202 if (so->so_nbio && so->so_qlen == 0) { 203 error = EWOULDBLOCK; 204 goto bad; 205 } 206 while (so->so_qlen == 0 && so->so_error == 0) { 207 if (so->so_state & SS_CANTRCVMORE) { 208 so->so_error = ECONNABORTED; 209 break; 210 } 211 if (wakeup_state & SS_RESTARTSYS) { 212 error = ERESTART; 213 goto bad; 214 } 215 error = sowait(so, true, 0); 216 if (error) { 217 goto bad; 218 } 219 wakeup_state = so->so_state; 220 } 221 if (so->so_error) { 222 error = so->so_error; 223 so->so_error = 0; 224 goto bad; 225 } 226 /* connection has been removed from the listen queue */ 227 KNOTE(&so->so_rcv.sb_sel.sel_klist, NOTE_SUBMIT); 228 so2 = TAILQ_FIRST(&so->so_q); 229 if (soqremque(so2, 1) == 0) 230 panic("accept"); 231 fp2->f_type = DTYPE_SOCKET; 232 fp2->f_flag = (fp->f_flag & ~clrflags) | 233 ((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0); 234 fp2->f_ops = &socketops; 235 fp2->f_data = so2; 236 error = soaccept(so2, nam); 237 so2->so_cred = kauth_cred_dup(so->so_cred); 238 sounlock(so); 239 if (error) { 240 /* an error occurred, free the file descriptor and mbuf */ 241 m_freem(nam); 242 mutex_enter(&fp2->f_lock); 243 fp2->f_count++; 244 mutex_exit(&fp2->f_lock); 245 closef(fp2); 246 fd_abort(curproc, NULL, fd); 247 } else { 248 fd_set_exclose(l, fd, (flags & SOCK_CLOEXEC) != 0); 249 fd_affix(curproc, fp2, fd); 250 *name = nam; 251 } 252 fd_putfile(sock); 253 if (__predict_false(mask)) 254 sigsuspendteardown(l); 255 return (error); 256 bad: 257 sounlock(so); 258 m_freem(nam); 259 fd_putfile(sock); 260 fd_abort(curproc, fp2, fd); 261 if (__predict_false(mask)) 262 sigsuspendteardown(l); 263 return (error); 264 } 265 266 int 267 sys_accept(struct lwp *l, const struct sys_accept_args *uap, register_t *retval) 268 { 269 /* { 270 syscallarg(int) s; 271 syscallarg(struct sockaddr *) name; 272 syscallarg(unsigned int *) anamelen; 273 } */ 274 int error, fd; 275 struct mbuf *name; 276 277 error = do_sys_accept(l, SCARG(uap, s), &name, retval, NULL, 0, 0); 278 if (error != 0) 279 return error; 280 error = copyout_sockname(SCARG(uap, name), SCARG(uap, anamelen), 281 MSG_LENUSRSPACE, name); 282 if (name != NULL) 283 m_free(name); 284 if (error != 0) { 285 fd = (int)*retval; 286 if (fd_getfile(fd) != NULL) 287 (void)fd_close(fd); 288 } 289 return error; 290 } 291 292 int 293 sys_paccept(struct lwp *l, const struct sys_paccept_args *uap, 294 register_t *retval) 295 { 296 /* { 297 syscallarg(int) s; 298 syscallarg(struct sockaddr *) name; 299 syscallarg(unsigned int *) anamelen; 300 syscallarg(const sigset_t *) mask; 301 syscallarg(int) flags; 302 } */ 303 int error, fd; 304 struct mbuf *name; 305 sigset_t *mask, amask; 306 307 if (SCARG(uap, mask) != NULL) { 308 error = copyin(SCARG(uap, mask), &amask, sizeof(amask)); 309 if (error) 310 return error; 311 mask = &amask; 312 } else 313 mask = NULL; 314 315 error = do_sys_accept(l, SCARG(uap, s), &name, retval, mask, 316 SCARG(uap, flags), FNONBLOCK); 317 if (error != 0) 318 return error; 319 error = copyout_sockname(SCARG(uap, name), SCARG(uap, anamelen), 320 MSG_LENUSRSPACE, name); 321 if (name != NULL) 322 m_free(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 /* ARGSUSED */ 332 int 333 sys_connect(struct lwp *l, const struct sys_connect_args *uap, 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 mbuf *nam; 342 343 error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen), 344 MT_SONAME); 345 if (error) 346 return error; 347 return do_sys_connect(l, SCARG(uap, s), nam); 348 } 349 350 int 351 do_sys_connect(struct lwp *l, int fd, struct mbuf *nam) 352 { 353 struct socket *so; 354 int error; 355 int interrupted = 0; 356 357 if ((error = fd_getsock(fd, &so)) != 0) { 358 m_freem(nam); 359 return (error); 360 } 361 solock(so); 362 MCLAIM(nam, so->so_mowner); 363 if ((so->so_state & SS_ISCONNECTING) != 0) { 364 error = EALREADY; 365 goto out; 366 } 367 368 error = soconnect(so, nam, l); 369 if (error) 370 goto bad; 371 if (so->so_nbio && (so->so_state & SS_ISCONNECTING) != 0) { 372 error = EINPROGRESS; 373 goto out; 374 } 375 while ((so->so_state & SS_ISCONNECTING) != 0 && so->so_error == 0) { 376 error = sowait(so, true, 0); 377 if (__predict_false((so->so_state & SS_ISABORTING) != 0)) { 378 error = EPIPE; 379 interrupted = 1; 380 break; 381 } 382 if (error) { 383 if (error == EINTR || error == ERESTART) 384 interrupted = 1; 385 break; 386 } 387 } 388 if (error == 0) { 389 error = so->so_error; 390 so->so_error = 0; 391 } 392 bad: 393 if (!interrupted) 394 so->so_state &= ~SS_ISCONNECTING; 395 if (error == ERESTART) 396 error = EINTR; 397 out: 398 sounlock(so); 399 fd_putfile(fd); 400 m_freem(nam); 401 return (error); 402 } 403 404 int 405 sys_socketpair(struct lwp *l, const struct sys_socketpair_args *uap, register_t *retval) 406 { 407 /* { 408 syscallarg(int) domain; 409 syscallarg(int) type; 410 syscallarg(int) protocol; 411 syscallarg(int *) rsv; 412 } */ 413 file_t *fp1, *fp2; 414 struct socket *so1, *so2; 415 int fd, error, sv[2]; 416 proc_t *p; 417 int flags = SCARG(uap, type) & SOCK_FLAGS_MASK; 418 int type = SCARG(uap, type) & ~SOCK_FLAGS_MASK; 419 int fnonblock = (flags & SOCK_NONBLOCK) ? FNONBLOCK : 0; 420 421 p = curproc; 422 error = socreate(SCARG(uap, domain), &so1, type, 423 SCARG(uap, protocol), l, NULL); 424 if (error) 425 return (error); 426 error = socreate(SCARG(uap, domain), &so2, type, 427 SCARG(uap, protocol), l, so1); 428 if (error) 429 goto free1; 430 if ((error = fd_allocfile(&fp1, &fd)) != 0) 431 goto free2; 432 fd_set_exclose(l, fd, (flags & SOCK_CLOEXEC) != 0); 433 sv[0] = fd; 434 fp1->f_flag = FREAD|FWRITE|fnonblock; 435 fp1->f_type = DTYPE_SOCKET; 436 fp1->f_ops = &socketops; 437 fp1->f_data = so1; 438 if ((error = fd_allocfile(&fp2, &fd)) != 0) 439 goto free3; 440 fd_set_exclose(l, fd, (flags & SOCK_CLOEXEC) != 0); 441 fp2->f_flag = FREAD|FWRITE|fnonblock; 442 fp2->f_type = DTYPE_SOCKET; 443 fp2->f_ops = &socketops; 444 fp2->f_data = so2; 445 sv[1] = fd; 446 solock(so1); 447 error = soconnect2(so1, so2); 448 if (error == 0 && SCARG(uap, type) == SOCK_DGRAM) { 449 /* 450 * Datagram socket connection is asymmetric. 451 */ 452 error = soconnect2(so2, so1); 453 } 454 sounlock(so1); 455 if (error == 0) 456 error = copyout(sv, SCARG(uap, rsv), 2 * sizeof(int)); 457 if (error == 0) { 458 fd_affix(p, fp2, sv[1]); 459 fd_affix(p, fp1, sv[0]); 460 return (0); 461 } 462 fd_abort(p, fp2, sv[1]); 463 free3: 464 fd_abort(p, fp1, sv[0]); 465 free2: 466 (void)soclose(so2); 467 free1: 468 (void)soclose(so1); 469 return (error); 470 } 471 472 int 473 sys_sendto(struct lwp *l, const struct sys_sendto_args *uap, register_t *retval) 474 { 475 /* { 476 syscallarg(int) s; 477 syscallarg(const void *) buf; 478 syscallarg(size_t) len; 479 syscallarg(int) flags; 480 syscallarg(const struct sockaddr *) to; 481 syscallarg(unsigned int) tolen; 482 } */ 483 struct msghdr msg; 484 struct iovec aiov; 485 486 msg.msg_name = __UNCONST(SCARG(uap, to)); /* XXXUNCONST kills const */ 487 msg.msg_namelen = SCARG(uap, tolen); 488 msg.msg_iov = &aiov; 489 msg.msg_iovlen = 1; 490 msg.msg_control = NULL; 491 msg.msg_flags = 0; 492 aiov.iov_base = __UNCONST(SCARG(uap, buf)); /* XXXUNCONST kills const */ 493 aiov.iov_len = SCARG(uap, len); 494 return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), retval); 495 } 496 497 int 498 sys_sendmsg(struct lwp *l, const struct sys_sendmsg_args *uap, register_t *retval) 499 { 500 /* { 501 syscallarg(int) s; 502 syscallarg(const struct msghdr *) msg; 503 syscallarg(int) flags; 504 } */ 505 struct msghdr msg; 506 int error; 507 508 error = copyin(SCARG(uap, msg), &msg, sizeof(msg)); 509 if (error) 510 return (error); 511 512 msg.msg_flags = MSG_IOVUSRSPACE; 513 return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), retval); 514 } 515 516 int 517 do_sys_sendmsg(struct lwp *l, int s, struct msghdr *mp, int flags, 518 register_t *retsize) 519 { 520 struct iovec aiov[UIO_SMALLIOV], *iov = aiov, *tiov, *ktriov = NULL; 521 struct mbuf *to, *control; 522 struct socket *so; 523 struct uio auio; 524 size_t len, iovsz; 525 int i, error; 526 527 ktrkuser("msghdr", mp, sizeof *mp); 528 529 /* If the caller passed us stuff in mbufs, we must free them. */ 530 to = (mp->msg_flags & MSG_NAMEMBUF) ? mp->msg_name : NULL; 531 control = (mp->msg_flags & MSG_CONTROLMBUF) ? mp->msg_control : NULL; 532 iovsz = mp->msg_iovlen * sizeof(struct iovec); 533 534 if (mp->msg_flags & MSG_IOVUSRSPACE) { 535 if ((unsigned int)mp->msg_iovlen > UIO_SMALLIOV) { 536 if ((unsigned int)mp->msg_iovlen > IOV_MAX) { 537 error = EMSGSIZE; 538 goto bad; 539 } 540 iov = kmem_alloc(iovsz, KM_SLEEP); 541 } 542 if (mp->msg_iovlen != 0) { 543 error = copyin(mp->msg_iov, iov, iovsz); 544 if (error) 545 goto bad; 546 } 547 mp->msg_iov = iov; 548 } 549 550 auio.uio_iov = mp->msg_iov; 551 auio.uio_iovcnt = mp->msg_iovlen; 552 auio.uio_rw = UIO_WRITE; 553 auio.uio_offset = 0; /* XXX */ 554 auio.uio_resid = 0; 555 KASSERT(l == curlwp); 556 auio.uio_vmspace = l->l_proc->p_vmspace; 557 558 for (i = 0, tiov = mp->msg_iov; i < mp->msg_iovlen; i++, tiov++) { 559 /* 560 * Writes return ssize_t because -1 is returned on error. 561 * Therefore, we must restrict the length to SSIZE_MAX to 562 * avoid garbage return values. 563 */ 564 auio.uio_resid += tiov->iov_len; 565 if (tiov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) { 566 error = EINVAL; 567 goto bad; 568 } 569 } 570 571 if (mp->msg_name && to == NULL) { 572 error = sockargs(&to, mp->msg_name, mp->msg_namelen, 573 MT_SONAME); 574 if (error) 575 goto bad; 576 } 577 578 if (mp->msg_control) { 579 if (mp->msg_controllen < CMSG_ALIGN(sizeof(struct cmsghdr))) { 580 error = EINVAL; 581 goto bad; 582 } 583 if (control == NULL) { 584 error = sockargs(&control, mp->msg_control, 585 mp->msg_controllen, MT_CONTROL); 586 if (error) 587 goto bad; 588 } 589 } 590 591 if (ktrpoint(KTR_GENIO)) { 592 ktriov = kmem_alloc(iovsz, KM_SLEEP); 593 memcpy(ktriov, auio.uio_iov, iovsz); 594 } 595 596 if ((error = fd_getsock(s, &so)) != 0) 597 goto bad; 598 599 if (mp->msg_name) 600 MCLAIM(to, so->so_mowner); 601 if (mp->msg_control) 602 MCLAIM(control, so->so_mowner); 603 604 len = auio.uio_resid; 605 error = (*so->so_send)(so, to, &auio, NULL, control, flags, l); 606 /* Protocol is responsible for freeing 'control' */ 607 control = NULL; 608 609 fd_putfile(s); 610 611 if (error) { 612 if (auio.uio_resid != len && (error == ERESTART || 613 error == EINTR || error == EWOULDBLOCK)) 614 error = 0; 615 if (error == EPIPE && (flags & MSG_NOSIGNAL) == 0) { 616 mutex_enter(proc_lock); 617 psignal(l->l_proc, SIGPIPE); 618 mutex_exit(proc_lock); 619 } 620 } 621 if (error == 0) 622 *retsize = len - auio.uio_resid; 623 624 bad: 625 if (ktriov != NULL) { 626 ktrgeniov(s, UIO_WRITE, ktriov, *retsize, error); 627 kmem_free(ktriov, iovsz); 628 } 629 630 if (iov != aiov) 631 kmem_free(iov, iovsz); 632 if (to) 633 m_freem(to); 634 if (control) 635 m_freem(control); 636 637 return (error); 638 } 639 640 int 641 sys_recvfrom(struct lwp *l, const struct sys_recvfrom_args *uap, register_t *retval) 642 { 643 /* { 644 syscallarg(int) s; 645 syscallarg(void *) buf; 646 syscallarg(size_t) len; 647 syscallarg(int) flags; 648 syscallarg(struct sockaddr *) from; 649 syscallarg(unsigned int *) fromlenaddr; 650 } */ 651 struct msghdr msg; 652 struct iovec aiov; 653 int error; 654 struct mbuf *from; 655 656 msg.msg_name = NULL; 657 msg.msg_iov = &aiov; 658 msg.msg_iovlen = 1; 659 aiov.iov_base = SCARG(uap, buf); 660 aiov.iov_len = SCARG(uap, len); 661 msg.msg_control = NULL; 662 msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS; 663 664 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, NULL, retval); 665 if (error != 0) 666 return error; 667 668 error = copyout_sockname(SCARG(uap, from), SCARG(uap, fromlenaddr), 669 MSG_LENUSRSPACE, from); 670 if (from != NULL) 671 m_free(from); 672 return error; 673 } 674 675 int 676 sys_recvmsg(struct lwp *l, const struct sys_recvmsg_args *uap, register_t *retval) 677 { 678 /* { 679 syscallarg(int) s; 680 syscallarg(struct msghdr *) msg; 681 syscallarg(int) flags; 682 } */ 683 struct msghdr msg; 684 int error; 685 struct mbuf *from, *control; 686 687 error = copyin(SCARG(uap, msg), &msg, sizeof(msg)); 688 if (error) 689 return (error); 690 691 msg.msg_flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE; 692 693 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, 694 msg.msg_control != NULL ? &control : NULL, retval); 695 if (error != 0) 696 return error; 697 698 if (msg.msg_control != NULL) 699 error = copyout_msg_control(l, &msg, control); 700 701 if (error == 0) 702 error = copyout_sockname(msg.msg_name, &msg.msg_namelen, 0, 703 from); 704 if (from != NULL) 705 m_free(from); 706 if (error == 0) { 707 ktrkuser("msghdr", &msg, sizeof msg); 708 error = copyout(&msg, SCARG(uap, msg), sizeof(msg)); 709 } 710 711 return (error); 712 } 713 714 /* 715 * Adjust for a truncated SCM_RIGHTS control message. 716 * This means closing any file descriptors that aren't present 717 * in the returned buffer. 718 * m is the mbuf holding the (already externalized) SCM_RIGHTS message. 719 */ 720 static void 721 free_rights(struct mbuf *m) 722 { 723 int nfd; 724 int i; 725 int *fdv; 726 727 nfd = m->m_len < CMSG_SPACE(sizeof(int)) ? 0 728 : (m->m_len - CMSG_SPACE(sizeof(int))) / sizeof(int) + 1; 729 fdv = (int *) CMSG_DATA(mtod(m,struct cmsghdr *)); 730 for (i = 0; i < nfd; i++) { 731 if (fd_getfile(fdv[i]) != NULL) 732 (void)fd_close(fdv[i]); 733 } 734 } 735 736 void 737 free_control_mbuf(struct lwp *l, struct mbuf *control, struct mbuf *uncopied) 738 { 739 struct mbuf *next; 740 struct cmsghdr *cmsg; 741 bool do_free_rights = false; 742 743 while (control != NULL) { 744 cmsg = mtod(control, struct cmsghdr *); 745 if (control == uncopied) 746 do_free_rights = true; 747 if (do_free_rights && cmsg->cmsg_level == SOL_SOCKET 748 && cmsg->cmsg_type == SCM_RIGHTS) 749 free_rights(control); 750 next = control->m_next; 751 m_free(control); 752 control = next; 753 } 754 } 755 756 /* Copy socket control/CMSG data to user buffer, frees the mbuf */ 757 int 758 copyout_msg_control(struct lwp *l, struct msghdr *mp, struct mbuf *control) 759 { 760 int i, len, error = 0; 761 struct cmsghdr *cmsg; 762 struct mbuf *m; 763 char *q; 764 765 len = mp->msg_controllen; 766 if (len <= 0 || control == 0) { 767 mp->msg_controllen = 0; 768 free_control_mbuf(l, control, control); 769 return 0; 770 } 771 772 q = (char *)mp->msg_control; 773 774 for (m = control; m != NULL; ) { 775 cmsg = mtod(m, struct cmsghdr *); 776 i = m->m_len; 777 if (len < i) { 778 mp->msg_flags |= MSG_CTRUNC; 779 if (cmsg->cmsg_level == SOL_SOCKET 780 && cmsg->cmsg_type == SCM_RIGHTS) 781 /* Do not truncate me ... */ 782 break; 783 i = len; 784 } 785 error = copyout(mtod(m, void *), q, i); 786 ktrkuser("msgcontrol", mtod(m, void *), i); 787 if (error != 0) { 788 /* We must free all the SCM_RIGHTS */ 789 m = control; 790 break; 791 } 792 m = m->m_next; 793 if (m) 794 i = ALIGN(i); 795 q += i; 796 len -= i; 797 if (len <= 0) 798 break; 799 } 800 801 free_control_mbuf(l, control, m); 802 803 mp->msg_controllen = q - (char *)mp->msg_control; 804 return error; 805 } 806 807 int 808 do_sys_recvmsg(struct lwp *l, int s, struct msghdr *mp, struct mbuf **from, 809 struct mbuf **control, register_t *retsize) 810 { 811 struct iovec aiov[UIO_SMALLIOV], *iov = aiov, *tiov, *ktriov; 812 struct socket *so; 813 struct uio auio; 814 size_t len, iovsz; 815 int i, error; 816 817 ktrkuser("msghdr", mp, sizeof *mp); 818 819 *from = NULL; 820 if (control != NULL) 821 *control = NULL; 822 823 if ((error = fd_getsock(s, &so)) != 0) 824 return (error); 825 826 iovsz = mp->msg_iovlen * sizeof(struct iovec); 827 828 if (mp->msg_flags & MSG_IOVUSRSPACE) { 829 if ((unsigned int)mp->msg_iovlen > UIO_SMALLIOV) { 830 if ((unsigned int)mp->msg_iovlen > IOV_MAX) { 831 error = EMSGSIZE; 832 goto out; 833 } 834 iov = kmem_alloc(iovsz, KM_SLEEP); 835 } 836 if (mp->msg_iovlen != 0) { 837 error = copyin(mp->msg_iov, iov, iovsz); 838 if (error) 839 goto out; 840 } 841 auio.uio_iov = iov; 842 } else 843 auio.uio_iov = mp->msg_iov; 844 auio.uio_iovcnt = mp->msg_iovlen; 845 auio.uio_rw = UIO_READ; 846 auio.uio_offset = 0; /* XXX */ 847 auio.uio_resid = 0; 848 KASSERT(l == curlwp); 849 auio.uio_vmspace = l->l_proc->p_vmspace; 850 851 tiov = auio.uio_iov; 852 for (i = 0; i < mp->msg_iovlen; i++, tiov++) { 853 /* 854 * Reads return ssize_t because -1 is returned on error. 855 * Therefore we must restrict the length to SSIZE_MAX to 856 * avoid garbage return values. 857 */ 858 auio.uio_resid += tiov->iov_len; 859 if (tiov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) { 860 error = EINVAL; 861 goto out; 862 } 863 } 864 865 ktriov = NULL; 866 if (ktrpoint(KTR_GENIO)) { 867 ktriov = kmem_alloc(iovsz, KM_SLEEP); 868 memcpy(ktriov, auio.uio_iov, iovsz); 869 } 870 871 len = auio.uio_resid; 872 mp->msg_flags &= MSG_USERFLAGS; 873 error = (*so->so_receive)(so, from, &auio, NULL, control, 874 &mp->msg_flags); 875 len -= auio.uio_resid; 876 *retsize = len; 877 if (error != 0 && len != 0 878 && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) 879 /* Some data transferred */ 880 error = 0; 881 882 if (ktriov != NULL) { 883 ktrgeniov(s, UIO_READ, ktriov, len, error); 884 kmem_free(ktriov, iovsz); 885 } 886 887 if (error != 0) { 888 m_freem(*from); 889 *from = NULL; 890 if (control != NULL) { 891 free_control_mbuf(l, *control, *control); 892 *control = NULL; 893 } 894 } 895 out: 896 if (iov != aiov) 897 kmem_free(iov, iovsz); 898 fd_putfile(s); 899 return (error); 900 } 901 902 903 /* ARGSUSED */ 904 int 905 sys_shutdown(struct lwp *l, const struct sys_shutdown_args *uap, register_t *retval) 906 { 907 /* { 908 syscallarg(int) s; 909 syscallarg(int) how; 910 } */ 911 struct socket *so; 912 int error; 913 914 if ((error = fd_getsock(SCARG(uap, s), &so)) != 0) 915 return (error); 916 solock(so); 917 error = soshutdown(so, SCARG(uap, how)); 918 sounlock(so); 919 fd_putfile(SCARG(uap, s)); 920 return (error); 921 } 922 923 /* ARGSUSED */ 924 int 925 sys_setsockopt(struct lwp *l, const struct sys_setsockopt_args *uap, register_t *retval) 926 { 927 /* { 928 syscallarg(int) s; 929 syscallarg(int) level; 930 syscallarg(int) name; 931 syscallarg(const void *) val; 932 syscallarg(unsigned int) valsize; 933 } */ 934 struct sockopt sopt; 935 struct socket *so; 936 int error; 937 unsigned int len; 938 939 len = SCARG(uap, valsize); 940 if (len > 0 && SCARG(uap, val) == NULL) 941 return (EINVAL); 942 943 if (len > MCLBYTES) 944 return (EINVAL); 945 946 if ((error = fd_getsock(SCARG(uap, s), &so)) != 0) 947 return (error); 948 949 sockopt_init(&sopt, SCARG(uap, level), SCARG(uap, name), len); 950 951 if (len > 0) { 952 error = copyin(SCARG(uap, val), sopt.sopt_data, len); 953 if (error) 954 goto out; 955 } 956 957 error = sosetopt(so, &sopt); 958 959 out: 960 sockopt_destroy(&sopt); 961 fd_putfile(SCARG(uap, s)); 962 return (error); 963 } 964 965 /* ARGSUSED */ 966 int 967 sys_getsockopt(struct lwp *l, const struct sys_getsockopt_args *uap, register_t *retval) 968 { 969 /* { 970 syscallarg(int) s; 971 syscallarg(int) level; 972 syscallarg(int) name; 973 syscallarg(void *) val; 974 syscallarg(unsigned int *) avalsize; 975 } */ 976 struct sockopt sopt; 977 struct socket *so; 978 unsigned int valsize, len; 979 int error; 980 981 if (SCARG(uap, val) != NULL) { 982 error = copyin(SCARG(uap, avalsize), &valsize, sizeof(valsize)); 983 if (error) 984 return (error); 985 } else 986 valsize = 0; 987 988 if ((error = fd_getsock(SCARG(uap, s), &so)) != 0) 989 return (error); 990 991 sockopt_init(&sopt, SCARG(uap, level), SCARG(uap, name), 0); 992 993 error = sogetopt(so, &sopt); 994 if (error) 995 goto out; 996 997 if (valsize > 0) { 998 len = min(valsize, sopt.sopt_size); 999 error = copyout(sopt.sopt_data, SCARG(uap, val), len); 1000 if (error) 1001 goto out; 1002 1003 error = copyout(&len, SCARG(uap, avalsize), sizeof(len)); 1004 if (error) 1005 goto out; 1006 } 1007 1008 out: 1009 sockopt_destroy(&sopt); 1010 fd_putfile(SCARG(uap, s)); 1011 return (error); 1012 } 1013 1014 #ifdef PIPE_SOCKETPAIR 1015 /* ARGSUSED */ 1016 int 1017 pipe1(struct lwp *l, register_t *retval, int flags) 1018 { 1019 file_t *rf, *wf; 1020 struct socket *rso, *wso; 1021 int fd, error; 1022 proc_t *p; 1023 1024 if (flags & ~(O_CLOEXEC|O_NONBLOCK)) 1025 return EINVAL; 1026 p = curproc; 1027 if ((error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, l, NULL)) != 0) 1028 return (error); 1029 if ((error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, l, rso)) != 0) 1030 goto free1; 1031 /* remember this socket pair implements a pipe */ 1032 wso->so_state |= SS_ISAPIPE; 1033 rso->so_state |= SS_ISAPIPE; 1034 if ((error = fd_allocfile(&rf, &fd)) != 0) 1035 goto free2; 1036 retval[0] = fd; 1037 rf->f_flag = FREAD | flags; 1038 rf->f_type = DTYPE_SOCKET; 1039 rf->f_ops = &socketops; 1040 rf->f_data = rso; 1041 if ((error = fd_allocfile(&wf, &fd)) != 0) 1042 goto free3; 1043 wf->f_flag = FWRITE | flags; 1044 wf->f_type = DTYPE_SOCKET; 1045 wf->f_ops = &socketops; 1046 wf->f_data = wso; 1047 retval[1] = fd; 1048 solock(wso); 1049 error = unp_connect2(wso, rso, PRU_CONNECT2); 1050 sounlock(wso); 1051 if (error != 0) 1052 goto free4; 1053 fd_affix(p, wf, (int)retval[1]); 1054 fd_affix(p, rf, (int)retval[0]); 1055 return (0); 1056 free4: 1057 fd_abort(p, wf, (int)retval[1]); 1058 free3: 1059 fd_abort(p, rf, (int)retval[0]); 1060 free2: 1061 (void)soclose(wso); 1062 free1: 1063 (void)soclose(rso); 1064 return (error); 1065 } 1066 #endif /* PIPE_SOCKETPAIR */ 1067 1068 /* 1069 * Get socket name. 1070 */ 1071 /* ARGSUSED */ 1072 int 1073 do_sys_getsockname(struct lwp *l, int fd, int which, struct mbuf **nam) 1074 { 1075 struct socket *so; 1076 struct mbuf *m; 1077 int error; 1078 1079 if ((error = fd_getsock(fd, &so)) != 0) 1080 return error; 1081 1082 m = m_getclr(M_WAIT, MT_SONAME); 1083 MCLAIM(m, so->so_mowner); 1084 1085 solock(so); 1086 if (which == PRU_PEERADDR 1087 && (so->so_state & (SS_ISCONNECTED | SS_ISCONFIRMING)) == 0) { 1088 error = ENOTCONN; 1089 } else { 1090 *nam = m; 1091 error = (*so->so_proto->pr_usrreq)(so, which, NULL, m, NULL, 1092 NULL); 1093 } 1094 sounlock(so); 1095 if (error != 0) 1096 m_free(m); 1097 fd_putfile(fd); 1098 return error; 1099 } 1100 1101 int 1102 copyout_sockname(struct sockaddr *asa, unsigned int *alen, int flags, 1103 struct mbuf *addr) 1104 { 1105 int len; 1106 int error; 1107 1108 if (asa == NULL) 1109 /* Assume application not interested */ 1110 return 0; 1111 1112 if (flags & MSG_LENUSRSPACE) { 1113 error = copyin(alen, &len, sizeof(len)); 1114 if (error) 1115 return error; 1116 } else 1117 len = *alen; 1118 if (len < 0) 1119 return EINVAL; 1120 1121 if (addr == NULL) { 1122 len = 0; 1123 error = 0; 1124 } else { 1125 if (len > addr->m_len) 1126 len = addr->m_len; 1127 /* Maybe this ought to copy a chain ? */ 1128 ktrkuser("sockname", mtod(addr, void *), len); 1129 error = copyout(mtod(addr, void *), asa, len); 1130 } 1131 1132 if (error == 0) { 1133 if (flags & MSG_LENUSRSPACE) 1134 error = copyout(&len, alen, sizeof(len)); 1135 else 1136 *alen = len; 1137 } 1138 1139 return error; 1140 } 1141 1142 /* 1143 * Get socket name. 1144 */ 1145 /* ARGSUSED */ 1146 int 1147 sys_getsockname(struct lwp *l, const struct sys_getsockname_args *uap, register_t *retval) 1148 { 1149 /* { 1150 syscallarg(int) fdes; 1151 syscallarg(struct sockaddr *) asa; 1152 syscallarg(unsigned int *) alen; 1153 } */ 1154 struct mbuf *m; 1155 int error; 1156 1157 error = do_sys_getsockname(l, SCARG(uap, fdes), PRU_SOCKADDR, &m); 1158 if (error != 0) 1159 return error; 1160 1161 error = copyout_sockname(SCARG(uap, asa), SCARG(uap, alen), 1162 MSG_LENUSRSPACE, m); 1163 if (m != NULL) 1164 m_free(m); 1165 return error; 1166 } 1167 1168 /* 1169 * Get name of peer for connected socket. 1170 */ 1171 /* ARGSUSED */ 1172 int 1173 sys_getpeername(struct lwp *l, const struct sys_getpeername_args *uap, register_t *retval) 1174 { 1175 /* { 1176 syscallarg(int) fdes; 1177 syscallarg(struct sockaddr *) asa; 1178 syscallarg(unsigned int *) alen; 1179 } */ 1180 struct mbuf *m; 1181 int error; 1182 1183 error = do_sys_getsockname(l, SCARG(uap, fdes), PRU_PEERADDR, &m); 1184 if (error != 0) 1185 return error; 1186 1187 error = copyout_sockname(SCARG(uap, asa), SCARG(uap, alen), 1188 MSG_LENUSRSPACE, m); 1189 if (m != NULL) 1190 m_free(m); 1191 return error; 1192 } 1193 1194 /* 1195 * XXX In a perfect world, we wouldn't pass around socket control 1196 * XXX arguments in mbufs, and this could go away. 1197 */ 1198 int 1199 sockargs(struct mbuf **mp, const void *bf, size_t buflen, int type) 1200 { 1201 struct sockaddr *sa; 1202 struct mbuf *m; 1203 int error; 1204 1205 /* 1206 * We can't allow socket names > UCHAR_MAX in length, since that 1207 * will overflow sa_len. Control data more than a page size in 1208 * length is just too much. 1209 */ 1210 if (buflen > (type == MT_SONAME ? UCHAR_MAX : PAGE_SIZE)) 1211 return (EINVAL); 1212 1213 /* Allocate an mbuf to hold the arguments. */ 1214 m = m_get(M_WAIT, type); 1215 /* can't claim. don't who to assign it to. */ 1216 if (buflen > MLEN) { 1217 /* 1218 * Won't fit into a regular mbuf, so we allocate just 1219 * enough external storage to hold the argument. 1220 */ 1221 MEXTMALLOC(m, buflen, M_WAITOK); 1222 } 1223 m->m_len = buflen; 1224 error = copyin(bf, mtod(m, void *), buflen); 1225 if (error) { 1226 (void) m_free(m); 1227 return (error); 1228 } 1229 ktrkuser("sockargs", mtod(m, void *), buflen); 1230 *mp = m; 1231 if (type == MT_SONAME) { 1232 sa = mtod(m, struct sockaddr *); 1233 #if BYTE_ORDER != BIG_ENDIAN 1234 /* 1235 * 4.3BSD compat thing - need to stay, since bind(2), 1236 * connect(2), sendto(2) were not versioned for COMPAT_43. 1237 */ 1238 if (sa->sa_family == 0 && sa->sa_len < AF_MAX) 1239 sa->sa_family = sa->sa_len; 1240 #endif 1241 sa->sa_len = buflen; 1242 } 1243 return (0); 1244 } 1245