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