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