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