The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/uipc_syscalls.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: uipc_syscalls.c,v 1.206 2022/07/01 22:30:51 riastradh 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.206 2022/07/01 22:30:51 riastradh Exp $");
   65 
   66 #ifdef _KERNEL_OPT
   67 #include "opt_pipe.h"
   68 #include "opt_sctp.h"
   69 #endif
   70 
   71 #define MBUFTYPES
   72 #include <sys/param.h>
   73 #include <sys/systm.h>
   74 #include <sys/filedesc.h>
   75 #include <sys/proc.h>
   76 #include <sys/file.h>
   77 #include <sys/buf.h>
   78 #include <sys/mbuf.h>
   79 #include <sys/protosw.h>
   80 #include <sys/socket.h>
   81 #include <sys/socketvar.h>
   82 #include <sys/signalvar.h>
   83 #include <sys/un.h>
   84 #include <sys/ktrace.h>
   85 #include <sys/event.h>
   86 #include <sys/atomic.h>
   87 #include <sys/kauth.h>
   88 
   89 #ifdef SCTP
   90 #include <netinet/sctp_uio.h>
   91 #include <netinet/sctp_peeloff.h>
   92 #endif
   93 
   94 #include <sys/mount.h>
   95 #include <sys/syscallargs.h>
   96 
   97 /*
   98  * System call interface to the socket abstraction.
   99  */
  100 extern const struct fileops socketops;
  101 
  102 static int      sockargs_sb(struct sockaddr_big *, const void *, socklen_t);
  103 
  104 int
  105 sys___socket30(struct lwp *l, const struct sys___socket30_args *uap,
  106     register_t *retval)
  107 {
  108         /* {
  109                 syscallarg(int) domain;
  110                 syscallarg(int) type;
  111                 syscallarg(int) protocol;
  112         } */
  113         int fd, error;
  114 
  115         error = fsocreate(SCARG(uap, domain), NULL, SCARG(uap, type),
  116             SCARG(uap, protocol), &fd);
  117         if (error == 0) {
  118                 *retval = fd;
  119         }
  120         return error;
  121 }
  122 
  123 int
  124 sys_bind(struct lwp *l, const struct sys_bind_args *uap, register_t *retval)
  125 {
  126         /* {
  127                 syscallarg(int)                         s;
  128                 syscallarg(const struct sockaddr *)     name;
  129                 syscallarg(unsigned int)                namelen;
  130         } */
  131         int             error;
  132         struct sockaddr_big sb;
  133 
  134         error = sockargs_sb(&sb, SCARG(uap, name), SCARG(uap, namelen));
  135         if (error)
  136                 return error;
  137 
  138         return do_sys_bind(l, SCARG(uap, s), (struct sockaddr *)&sb);
  139 }
  140 
  141 int
  142 do_sys_bind(struct lwp *l, int fd, struct sockaddr *nam)
  143 {
  144         struct socket   *so;
  145         int             error;
  146 
  147         if ((error = fd_getsock(fd, &so)) != 0)
  148                 return error;
  149         error = sobind(so, nam, l);
  150         fd_putfile(fd);
  151         return error;
  152 }
  153 
  154 int
  155 sys_listen(struct lwp *l, const struct sys_listen_args *uap, register_t *retval)
  156 {
  157         /* {
  158                 syscallarg(int) s;
  159                 syscallarg(int) backlog;
  160         } */
  161         struct socket   *so;
  162         int             error;
  163 
  164         if ((error = fd_getsock(SCARG(uap, s), &so)) != 0)
  165                 return (error);
  166         error = solisten(so, SCARG(uap, backlog), l);
  167         fd_putfile(SCARG(uap, s));
  168         return error;
  169 }
  170 
  171 int
  172 do_sys_accept(struct lwp *l, int sock, struct sockaddr *name,
  173     register_t *new_sock, const sigset_t *mask, int flags, int clrflags)
  174 {
  175         file_t          *fp, *fp2;
  176         int             error, fd;
  177         struct socket   *so, *so2;
  178         short           wakeup_state = 0;
  179 
  180         if ((fp = fd_getfile(sock)) == NULL)
  181                 return EBADF;
  182         if (fp->f_type != DTYPE_SOCKET) {
  183                 fd_putfile(sock);
  184                 return ENOTSOCK;
  185         }
  186         if ((error = fd_allocfile(&fp2, &fd)) != 0) {
  187                 fd_putfile(sock);
  188                 return error;
  189         }
  190         *new_sock = fd;
  191         so = fp->f_socket;
  192         solock(so);
  193 
  194         if (__predict_false(mask))
  195                 sigsuspendsetup(l, mask);
  196 
  197         if (!(so->so_proto->pr_flags & PR_LISTEN)) {
  198                 error = EOPNOTSUPP;
  199                 goto bad;
  200         }
  201         if ((so->so_options & SO_ACCEPTCONN) == 0) {
  202                 error = EINVAL;
  203                 goto bad;
  204         }
  205         if ((so->so_state & SS_NBIO) && so->so_qlen == 0) {
  206                 error = EWOULDBLOCK;
  207                 goto bad;
  208         }
  209         while (so->so_qlen == 0 && so->so_error == 0) {
  210                 if (so->so_state & SS_CANTRCVMORE) {
  211                         so->so_error = ECONNABORTED;
  212                         break;
  213                 }
  214                 if (wakeup_state & SS_RESTARTSYS) {
  215                         error = ERESTART;
  216                         goto bad;
  217                 }
  218                 error = sowait(so, true, 0);
  219                 if (error) {
  220                         goto bad;
  221                 }
  222                 wakeup_state = so->so_state;
  223         }
  224         if (so->so_error) {
  225                 error = so->so_error;
  226                 so->so_error = 0;
  227                 goto bad;
  228         }
  229         /* connection has been removed from the listen queue */
  230         KNOTE(&so->so_rcv.sb_sel.sel_klist, NOTE_SUBMIT);
  231         so2 = TAILQ_FIRST(&so->so_q);
  232         if (soqremque(so2, 1) == 0)
  233                 panic("accept");
  234         fp2->f_type = DTYPE_SOCKET;
  235         fp2->f_flag = (fp->f_flag & ~clrflags) |
  236             ((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0)|
  237             ((flags & SOCK_NOSIGPIPE) ? FNOSIGPIPE : 0);
  238         fp2->f_ops = &socketops;
  239         fp2->f_socket = so2;
  240         if (fp2->f_flag & FNONBLOCK)
  241                 so2->so_state |= SS_NBIO;
  242         else
  243                 so2->so_state &= ~SS_NBIO;
  244         error = soaccept(so2, name);
  245         so2->so_cred = kauth_cred_dup(so->so_cred);
  246         sounlock(so);
  247         if (error) {
  248                 /* an error occurred, free the file descriptor and mbuf */
  249                 mutex_enter(&fp2->f_lock);
  250                 fp2->f_count++;
  251                 mutex_exit(&fp2->f_lock);
  252                 closef(fp2);
  253                 fd_abort(curproc, NULL, fd);
  254         } else {
  255                 fd_set_exclose(l, fd, (flags & SOCK_CLOEXEC) != 0);
  256                 fd_affix(curproc, fp2, fd);
  257         }
  258         fd_putfile(sock);
  259         if (__predict_false(mask))
  260                 sigsuspendteardown(l);
  261         return error;
  262  bad:
  263         sounlock(so);
  264         fd_putfile(sock);
  265         fd_abort(curproc, fp2, fd);
  266         if (__predict_false(mask))
  267                 sigsuspendteardown(l);
  268         return error;
  269 }
  270 
  271 int
  272 sys_accept(struct lwp *l, const struct sys_accept_args *uap, register_t *retval)
  273 {
  274         /* {
  275                 syscallarg(int)                 s;
  276                 syscallarg(struct sockaddr *)   name;
  277                 syscallarg(unsigned int *)      anamelen;
  278         } */
  279         int error, fd;
  280         struct sockaddr_big name;
  281 
  282         name.sb_len = UCHAR_MAX;
  283         error = do_sys_accept(l, SCARG(uap, s), (struct sockaddr *)&name,
  284             retval, NULL, 0, 0);
  285         if (error != 0)
  286                 return error;
  287         error = copyout_sockname_sb(SCARG(uap, name), SCARG(uap, anamelen),
  288             MSG_LENUSRSPACE, &name);
  289         if (error != 0) {
  290                 fd = (int)*retval;
  291                 if (fd_getfile(fd) != NULL)
  292                         (void)fd_close(fd);
  293         }
  294         return error;
  295 }
  296 
  297 int
  298 sys_paccept(struct lwp *l, const struct sys_paccept_args *uap,
  299     register_t *retval)
  300 {
  301         /* {
  302                 syscallarg(int)                 s;
  303                 syscallarg(struct sockaddr *)   name;
  304                 syscallarg(unsigned int *)      anamelen;
  305                 syscallarg(const sigset_t *)    mask;
  306                 syscallarg(int)                 flags;
  307         } */
  308         int error, fd;
  309         struct sockaddr_big name;
  310         sigset_t *mask, amask;
  311 
  312         if (SCARG(uap, mask) != NULL) {
  313                 error = copyin(SCARG(uap, mask), &amask, sizeof(amask));
  314                 if (error)
  315                         return error;
  316                 mask = &amask;
  317         } else
  318                 mask = NULL;
  319 
  320         name.sb_len = UCHAR_MAX;
  321         error = do_sys_accept(l, SCARG(uap, s), (struct sockaddr *)&name,
  322             retval, mask, SCARG(uap, flags), FNONBLOCK);
  323         if (error != 0)
  324                 return error;
  325         error = copyout_sockname_sb(SCARG(uap, name), SCARG(uap, anamelen),
  326             MSG_LENUSRSPACE, &name);
  327         if (error != 0) {
  328                 fd = (int)*retval;
  329                 if (fd_getfile(fd) != NULL)
  330                         (void)fd_close(fd);
  331         }
  332         return error;
  333 }
  334 
  335 int
  336 sys_connect(struct lwp *l, const struct sys_connect_args *uap,
  337     register_t *retval)
  338 {
  339         /* {
  340                 syscallarg(int)                         s;
  341                 syscallarg(const struct sockaddr *)     name;
  342                 syscallarg(unsigned int)                namelen;
  343         } */
  344         int             error;
  345         struct sockaddr_big sbig;
  346 
  347         error = sockargs_sb(&sbig, SCARG(uap, name), SCARG(uap, namelen));
  348         if (error)
  349                 return error;
  350         return do_sys_connect(l, SCARG(uap, s), (struct sockaddr *)&sbig);
  351 }
  352 
  353 int
  354 do_sys_connect(struct lwp *l, int fd, struct sockaddr *nam)
  355 {
  356         struct socket   *so;
  357         int             error;
  358         int             interrupted = 0;
  359 
  360         if ((error = fd_getsock(fd, &so)) != 0) {
  361                 return (error);
  362         }
  363         solock(so);
  364         if ((so->so_state & SS_ISCONNECTING) != 0) {
  365                 error = EALREADY;
  366                 goto out;
  367         }
  368 
  369         error = soconnect(so, nam, l);
  370         if (error)
  371                 goto bad;
  372         if ((so->so_state & (SS_NBIO|SS_ISCONNECTING)) ==
  373             (SS_NBIO|SS_ISCONNECTING)) {
  374                 error = EINPROGRESS;
  375                 goto out;
  376         }
  377         while ((so->so_state & SS_ISCONNECTING) != 0 && so->so_error == 0) {
  378                 error = sowait(so, true, 0);
  379                 if (__predict_false((so->so_state & SS_ISABORTING) != 0)) {
  380                         error = EPIPE;
  381                         interrupted = 1;
  382                         break;
  383                 }
  384                 if (error) {
  385                         if (error == EINTR || error == ERESTART)
  386                                 interrupted = 1;
  387                         break;
  388                 }
  389         }
  390         if (error == 0) {
  391                 error = so->so_error;
  392                 so->so_error = 0;
  393         }
  394  bad:
  395         if (!interrupted)
  396                 so->so_state &= ~SS_ISCONNECTING;
  397         if (error == ERESTART)
  398                 error = EINTR;
  399  out:
  400         sounlock(so);
  401         fd_putfile(fd);
  402         return error;
  403 }
  404 
  405 static int
  406 makesocket(struct lwp *l, file_t **fp, int *fd, int flags, int type,
  407     int domain, int proto, struct socket *soo)
  408 {
  409         struct socket *so;
  410         int error;
  411 
  412         if ((error = socreate(domain, &so, type, proto, l, soo)) != 0) {
  413                 return error;
  414         }
  415         if (flags & SOCK_NONBLOCK) {
  416                 so->so_state |= SS_NBIO;
  417         }
  418 
  419         if ((error = fd_allocfile(fp, fd)) != 0) {
  420                 soclose(so);
  421                 return error;
  422         }
  423         fd_set_exclose(l, *fd, (flags & SOCK_CLOEXEC) != 0);
  424         (*fp)->f_flag = FREAD|FWRITE|
  425             ((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0)|
  426             ((flags & SOCK_NOSIGPIPE) ? FNOSIGPIPE : 0);
  427         (*fp)->f_type = DTYPE_SOCKET;
  428         (*fp)->f_ops = &socketops;
  429         (*fp)->f_socket = so;
  430         return 0;
  431 }
  432 
  433 int
  434 sys_socketpair(struct lwp *l, const struct sys_socketpair_args *uap,
  435     register_t *retval)
  436 {
  437         /* {
  438                 syscallarg(int)         domain;
  439                 syscallarg(int)         type;
  440                 syscallarg(int)         protocol;
  441                 syscallarg(int *)       rsv;
  442         } */
  443         file_t          *fp1, *fp2;
  444         struct socket   *so1, *so2;
  445         int             fd, error, sv[2];
  446         proc_t          *p = curproc;
  447         int             flags = SCARG(uap, type) & SOCK_FLAGS_MASK;
  448         int             type = SCARG(uap, type) & ~SOCK_FLAGS_MASK;
  449         int             domain = SCARG(uap, domain);
  450         int             proto = SCARG(uap, protocol);
  451 
  452         error = makesocket(l, &fp1, &fd, flags, type, domain, proto, NULL);
  453         if (error)
  454                 return error;
  455         so1 = fp1->f_socket;
  456         sv[0] = fd;
  457 
  458         error = makesocket(l, &fp2, &fd, flags, type, domain, proto, so1);
  459         if (error)
  460                 goto out;
  461         so2 = fp2->f_socket;
  462         sv[1] = fd;
  463 
  464         solock(so1);
  465         error = soconnect2(so1, so2);
  466         if (error == 0 && type == SOCK_DGRAM) {
  467                 /*
  468                  * Datagram socket connection is asymmetric.
  469                  */
  470                 error = soconnect2(so2, so1);
  471         }
  472         sounlock(so1);
  473 
  474         if (error == 0)
  475                 error = copyout(sv, SCARG(uap, rsv), sizeof(sv));
  476         if (error == 0) {
  477                 fd_affix(p, fp2, sv[1]);
  478                 fd_affix(p, fp1, sv[0]);
  479                 return 0;
  480         }
  481         fd_abort(p, fp2, sv[1]);
  482         (void)soclose(so2);
  483 out:
  484         fd_abort(p, fp1, sv[0]);
  485         (void)soclose(so1);
  486         return error;
  487 }
  488 
  489 int
  490 sys_sendto(struct lwp *l, const struct sys_sendto_args *uap,
  491     register_t *retval)
  492 {
  493         /* {
  494                 syscallarg(int)                         s;
  495                 syscallarg(const void *)                buf;
  496                 syscallarg(size_t)                      len;
  497                 syscallarg(int)                         flags;
  498                 syscallarg(const struct sockaddr *)     to;
  499                 syscallarg(unsigned int)                tolen;
  500         } */
  501         struct msghdr   msg = {0};
  502         struct iovec    aiov;
  503 
  504         msg.msg_name = __UNCONST(SCARG(uap, to)); /* XXXUNCONST kills const */
  505         msg.msg_namelen = SCARG(uap, tolen);
  506         msg.msg_iov = &aiov;
  507         msg.msg_iovlen = 1;
  508         msg.msg_control = NULL;
  509         msg.msg_flags = 0;
  510         aiov.iov_base = __UNCONST(SCARG(uap, buf)); /* XXXUNCONST kills const */
  511         aiov.iov_len = SCARG(uap, len);
  512         return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags),
  513             retval);
  514 }
  515 
  516 int
  517 sys_sendmsg(struct lwp *l, const struct sys_sendmsg_args *uap,
  518     register_t *retval)
  519 {
  520         /* {
  521                 syscallarg(int)                         s;
  522                 syscallarg(const struct msghdr *)       msg;
  523                 syscallarg(int)                         flags;
  524         } */
  525         struct msghdr   msg;
  526         int             error;
  527 
  528         error = copyin(SCARG(uap, msg), &msg, sizeof(msg));
  529         if (error)
  530                 return (error);
  531 
  532         msg.msg_flags = MSG_IOVUSRSPACE;
  533         return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags),
  534             retval);
  535 }
  536 
  537 int
  538 do_sys_sendmsg_so(struct lwp *l, int s, struct socket *so, file_t *fp,
  539     struct msghdr *mp, int flags, register_t *retsize)
  540 {
  541 
  542         struct iovec    aiov[UIO_SMALLIOV], *iov = aiov, *tiov, *ktriov = NULL;
  543         struct sockaddr *sa = NULL;
  544         struct mbuf     *to, *control;
  545         struct uio      auio;
  546         size_t          len, iovsz;
  547         int             i, error;
  548 
  549         ktrkuser("msghdr", mp, sizeof(*mp));
  550 
  551         /* If the caller passed us stuff in mbufs, we must free them. */
  552         to = (mp->msg_flags & MSG_NAMEMBUF) ? mp->msg_name : NULL;
  553         control = (mp->msg_flags & MSG_CONTROLMBUF) ? mp->msg_control : NULL;
  554         iovsz = mp->msg_iovlen * sizeof(struct iovec);
  555 
  556         if (mp->msg_flags & MSG_IOVUSRSPACE) {
  557                 if ((unsigned int)mp->msg_iovlen > UIO_SMALLIOV) {
  558                         if ((unsigned int)mp->msg_iovlen > IOV_MAX) {
  559                                 error = EMSGSIZE;
  560                                 goto bad;
  561                         }
  562                         iov = kmem_alloc(iovsz, KM_SLEEP);
  563                 }
  564                 if (mp->msg_iovlen != 0) {
  565                         error = copyin(mp->msg_iov, iov, iovsz);
  566                         if (error)
  567                                 goto bad;
  568                 }
  569                 auio.uio_iov = iov;
  570         } else
  571                 auio.uio_iov = mp->msg_iov;
  572 
  573         auio.uio_iovcnt = mp->msg_iovlen;
  574         auio.uio_rw = UIO_WRITE;
  575         auio.uio_offset = 0;                    /* XXX */
  576         auio.uio_resid = 0;
  577         KASSERT(l == curlwp);
  578         auio.uio_vmspace = l->l_proc->p_vmspace;
  579 
  580         tiov = auio.uio_iov;
  581         for (i = 0; i < auio.uio_iovcnt; i++, tiov++) {
  582                 /*
  583                  * Writes return ssize_t because -1 is returned on error.
  584                  * Therefore, we must restrict the length to SSIZE_MAX to
  585                  * avoid garbage return values.
  586                  */
  587                 auio.uio_resid += tiov->iov_len;
  588                 if (tiov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
  589                         error = EINVAL;
  590                         goto bad;
  591                 }
  592         }
  593 
  594         if (mp->msg_name && to == NULL) {
  595                 error = sockargs(&to, mp->msg_name, mp->msg_namelen,
  596                     UIO_USERSPACE, MT_SONAME);
  597                 if (error)
  598                         goto bad;
  599         }
  600 
  601         if (mp->msg_control) {
  602                 if (mp->msg_controllen < CMSG_ALIGN(sizeof(struct cmsghdr))) {
  603                         error = EINVAL;
  604                         goto bad;
  605                 }
  606                 if (control == NULL) {
  607                         error = sockargs(&control, mp->msg_control,
  608                             mp->msg_controllen, UIO_USERSPACE, MT_CONTROL);
  609                         if (error)
  610                                 goto bad;
  611                 }
  612         }
  613 
  614         if (ktrpoint(KTR_GENIO) && iovsz > 0) {
  615                 ktriov = kmem_alloc(iovsz, KM_SLEEP);
  616                 memcpy(ktriov, auio.uio_iov, iovsz);
  617         }
  618 
  619         if (mp->msg_name)
  620                 MCLAIM(to, so->so_mowner);
  621         if (mp->msg_control)
  622                 MCLAIM(control, so->so_mowner);
  623 
  624         if (to) {
  625                 sa = mtod(to, struct sockaddr *);
  626         }
  627 
  628         len = auio.uio_resid;
  629         error = (*so->so_send)(so, sa, &auio, NULL, control, flags, l);
  630         /* Protocol is responsible for freeing 'control' */
  631         control = NULL;
  632 
  633         if (error) {
  634                 if (auio.uio_resid != len && (error == ERESTART ||
  635                     error == EINTR || error == EWOULDBLOCK))
  636                         error = 0;
  637                 if (error == EPIPE && (fp->f_flag & FNOSIGPIPE) == 0 &&
  638                     (flags & MSG_NOSIGNAL) == 0) {
  639                         mutex_enter(&proc_lock);
  640                         psignal(l->l_proc, SIGPIPE);
  641                         mutex_exit(&proc_lock);
  642                 }
  643         }
  644         if (error == 0)
  645                 *retsize = len - auio.uio_resid;
  646 
  647 bad:
  648         if (ktriov != NULL) {
  649                 ktrgeniov(s, UIO_WRITE, ktriov, *retsize, error);
  650                 kmem_free(ktriov, iovsz);
  651         }
  652 
  653         if (iov != aiov)
  654                 kmem_free(iov, iovsz);
  655         if (to)
  656                 m_freem(to);
  657         if (control)
  658                 m_freem(control);
  659 
  660         return error;
  661 }
  662 
  663 int
  664 do_sys_sendmsg(struct lwp *l, int s, struct msghdr *mp, int flags,
  665     register_t *retsize)
  666 {
  667         int             error;
  668         struct socket   *so;
  669         file_t          *fp;
  670 
  671         if ((error = fd_getsock1(s, &so, &fp)) != 0) {
  672                 /* We have to free msg_name and msg_control ourselves */
  673                 if (mp->msg_flags & MSG_NAMEMBUF)
  674                         m_freem(mp->msg_name);
  675                 if (mp->msg_flags & MSG_CONTROLMBUF)
  676                         m_freem(mp->msg_control);
  677                 return error;
  678         }
  679         error = do_sys_sendmsg_so(l, s, so, fp, mp, flags, retsize);
  680         /* msg_name and msg_control freed */
  681         fd_putfile(s);
  682         return error;
  683 }
  684 
  685 int
  686 sys_recvfrom(struct lwp *l, const struct sys_recvfrom_args *uap,
  687     register_t *retval)
  688 {
  689         /* {
  690                 syscallarg(int)                 s;
  691                 syscallarg(void *)              buf;
  692                 syscallarg(size_t)              len;
  693                 syscallarg(int)                 flags;
  694                 syscallarg(struct sockaddr *)   from;
  695                 syscallarg(unsigned int *)      fromlenaddr;
  696         } */
  697         struct msghdr   msg = {0};
  698         struct iovec    aiov;
  699         int             error;
  700         struct mbuf     *from;
  701 
  702         msg.msg_name = NULL;
  703         msg.msg_iov = &aiov;
  704         msg.msg_iovlen = 1;
  705         aiov.iov_base = SCARG(uap, buf);
  706         aiov.iov_len = SCARG(uap, len);
  707         msg.msg_control = NULL;
  708         msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
  709 
  710         error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, NULL, retval);
  711         if (error != 0)
  712                 return error;
  713 
  714         error = copyout_sockname(SCARG(uap, from), SCARG(uap, fromlenaddr),
  715             MSG_LENUSRSPACE, from);
  716         if (from != NULL)
  717                 m_free(from);
  718         return error;
  719 }
  720 
  721 int
  722 sys_recvmsg(struct lwp *l, const struct sys_recvmsg_args *uap,
  723     register_t *retval)
  724 {
  725         /* {
  726                 syscallarg(int)                 s;
  727                 syscallarg(struct msghdr *)     msg;
  728                 syscallarg(int)                 flags;
  729         } */
  730         struct msghdr   msg;
  731         int             error;
  732         struct mbuf     *from, *control;
  733 
  734         error = copyin(SCARG(uap, msg), &msg, sizeof(msg));
  735         if (error)
  736                 return error;
  737 
  738         msg.msg_flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE;
  739 
  740         error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
  741             msg.msg_control != NULL ? &control : NULL, retval);
  742         if (error != 0)
  743                 return error;
  744 
  745         if (msg.msg_control != NULL)
  746                 error = copyout_msg_control(l, &msg, control);
  747 
  748         if (error == 0)
  749                 error = copyout_sockname(msg.msg_name, &msg.msg_namelen, 0,
  750                         from);
  751         if (from != NULL)
  752                 m_free(from);
  753         if (error == 0) {
  754                 ktrkuser("msghdr", &msg, sizeof(msg));
  755                 error = copyout(&msg, SCARG(uap, msg), sizeof(msg));
  756         }
  757 
  758         return error;
  759 }
  760 
  761 int
  762 sys_sendmmsg(struct lwp *l, const struct sys_sendmmsg_args *uap,
  763     register_t *retval)
  764 {
  765         /* {
  766                 syscallarg(int)                 s;
  767                 syscallarg(struct mmsghdr *)    mmsg;
  768                 syscallarg(unsigned int)        vlen;
  769                 syscallarg(unsigned int)        flags;
  770         } */
  771         struct mmsghdr mmsg;
  772         struct socket *so;
  773         file_t *fp;
  774         struct msghdr *msg = &mmsg.msg_hdr;
  775         int error, s;
  776         unsigned int vlen, flags, dg;
  777 
  778         s = SCARG(uap, s);
  779         if ((error = fd_getsock1(s, &so, &fp)) != 0)
  780                 return error;
  781 
  782         vlen = SCARG(uap, vlen);
  783         if (vlen > 1024)
  784                 vlen = 1024;
  785 
  786         flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE;
  787 
  788         for (dg = 0; dg < vlen;) {
  789                 error = copyin(SCARG(uap, mmsg) + dg, &mmsg, sizeof(mmsg));
  790                 if (error)
  791                         break;
  792 
  793                 msg->msg_flags = flags;
  794 
  795                 error = do_sys_sendmsg_so(l, s, so, fp, msg, flags, retval);
  796                 if (error)
  797                         break;
  798 
  799                 ktrkuser("msghdr", msg, sizeof(*msg));
  800                 mmsg.msg_len = *retval;
  801                 error = copyout(&mmsg, SCARG(uap, mmsg) + dg, sizeof(mmsg));
  802                 if (error)
  803                         break;
  804                 dg++;
  805 
  806         }
  807 
  808         *retval = dg;
  809 
  810         fd_putfile(s);
  811 
  812         /*
  813          * If we succeeded at least once, return 0.
  814          */
  815         if (dg)
  816                 return 0;
  817         return error;
  818 }
  819 
  820 /*
  821  * Adjust for a truncated SCM_RIGHTS control message.
  822  *  This means closing any file descriptors that aren't present
  823  *  in the returned buffer.
  824  *  m is the mbuf holding the (already externalized) SCM_RIGHTS message.
  825  */
  826 static void
  827 free_rights(struct mbuf *m)
  828 {
  829         struct cmsghdr *cm;
  830         int *fdv;
  831         unsigned int nfds, i;
  832 
  833         KASSERT(sizeof(*cm) <= m->m_len);
  834         cm = mtod(m, struct cmsghdr *);
  835 
  836         KASSERT(CMSG_ALIGN(sizeof(*cm)) <= cm->cmsg_len);
  837         KASSERT(cm->cmsg_len <= m->m_len);
  838         nfds = (cm->cmsg_len - CMSG_ALIGN(sizeof(*cm))) / sizeof(int);
  839         fdv = (int *)CMSG_DATA(cm);
  840 
  841         for (i = 0; i < nfds; i++)
  842                 if (fd_getfile(fdv[i]) != NULL)
  843                         (void)fd_close(fdv[i]);
  844 }
  845 
  846 void
  847 free_control_mbuf(struct lwp *l, struct mbuf *control, struct mbuf *uncopied)
  848 {
  849         struct mbuf *next;
  850         struct cmsghdr *cmsg;
  851         bool do_free_rights = false;
  852 
  853         while (control != NULL) {
  854                 cmsg = mtod(control, struct cmsghdr *);
  855                 if (control == uncopied)
  856                         do_free_rights = true;
  857                 if (do_free_rights && cmsg->cmsg_level == SOL_SOCKET
  858                     && cmsg->cmsg_type == SCM_RIGHTS)
  859                         free_rights(control);
  860                 next = control->m_next;
  861                 m_free(control);
  862                 control = next;
  863         }
  864 }
  865 
  866 /* Copy socket control/CMSG data to user buffer, frees the mbuf */
  867 int
  868 copyout_msg_control(struct lwp *l, struct msghdr *mp, struct mbuf *control)
  869 {
  870         int i, len, error = 0;
  871         struct cmsghdr *cmsg;
  872         struct mbuf *m;
  873         char *q;
  874 
  875         len = mp->msg_controllen;
  876         if (len <= 0 || control == 0) {
  877                 mp->msg_controllen = 0;
  878                 free_control_mbuf(l, control, control);
  879                 return 0;
  880         }
  881 
  882         q = (char *)mp->msg_control;
  883 
  884         for (m = control; m != NULL; ) {
  885                 cmsg = mtod(m, struct cmsghdr *);
  886                 i = m->m_len;
  887                 if (len < i) {
  888                         mp->msg_flags |= MSG_CTRUNC;
  889                         if (cmsg->cmsg_level == SOL_SOCKET
  890                             && cmsg->cmsg_type == SCM_RIGHTS)
  891                                 /* Do not truncate me ... */
  892                                 break;
  893                         i = len;
  894                 }
  895                 error = copyout(mtod(m, void *), q, i);
  896                 ktrkuser(mbuftypes[MT_CONTROL], cmsg, cmsg->cmsg_len);
  897                 if (error != 0) {
  898                         /* We must free all the SCM_RIGHTS */
  899                         m = control;
  900                         break;
  901                 }
  902                 m = m->m_next;
  903                 if (m)
  904                         i = ALIGN(i);
  905                 q += i;
  906                 len -= i;
  907                 if (len <= 0)
  908                         break;
  909         }
  910 
  911         free_control_mbuf(l, control, m);
  912 
  913         mp->msg_controllen = q - (char *)mp->msg_control;
  914         return error;
  915 }
  916 
  917 int
  918 do_sys_recvmsg_so(struct lwp *l, int s, struct socket *so, struct msghdr *mp,
  919     struct mbuf **from, struct mbuf **control, register_t *retsize)
  920 {
  921         struct iovec    aiov[UIO_SMALLIOV], *iov = aiov, *tiov, *ktriov = NULL;
  922         struct uio      auio;
  923         size_t          len, iovsz;
  924         int             i, error;
  925 
  926         ktrkuser("msghdr", mp, sizeof(*mp));
  927 
  928         *from = NULL;
  929         if (control != NULL)
  930                 *control = NULL;
  931 
  932         iovsz = mp->msg_iovlen * sizeof(struct iovec);
  933 
  934         if (mp->msg_flags & MSG_IOVUSRSPACE) {
  935                 if ((unsigned int)mp->msg_iovlen > UIO_SMALLIOV) {
  936                         if ((unsigned int)mp->msg_iovlen > IOV_MAX) {
  937                                 error = EMSGSIZE;
  938                                 goto out;
  939                         }
  940                         iov = kmem_alloc(iovsz, KM_SLEEP);
  941                 }
  942                 if (mp->msg_iovlen != 0) {
  943                         error = copyin(mp->msg_iov, iov, iovsz);
  944                         if (error)
  945                                 goto out;
  946                 }
  947                 auio.uio_iov = iov;
  948         } else
  949                 auio.uio_iov = mp->msg_iov;
  950         auio.uio_iovcnt = mp->msg_iovlen;
  951         auio.uio_rw = UIO_READ;
  952         auio.uio_offset = 0;                    /* XXX */
  953         auio.uio_resid = 0;
  954         KASSERT(l == curlwp);
  955         auio.uio_vmspace = l->l_proc->p_vmspace;
  956 
  957         tiov = auio.uio_iov;
  958         for (i = 0; i < auio.uio_iovcnt; i++, tiov++) {
  959                 /*
  960                  * Reads return ssize_t because -1 is returned on error.
  961                  * Therefore we must restrict the length to SSIZE_MAX to
  962                  * avoid garbage return values.
  963                  */
  964                 auio.uio_resid += tiov->iov_len;
  965                 if (tiov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
  966                         error = EINVAL;
  967                         goto out;
  968                 }
  969         }
  970 
  971         if (ktrpoint(KTR_GENIO) && iovsz > 0) {
  972                 ktriov = kmem_alloc(iovsz, KM_SLEEP);
  973                 memcpy(ktriov, auio.uio_iov, iovsz);
  974         }
  975 
  976         len = auio.uio_resid;
  977         mp->msg_flags &= MSG_USERFLAGS;
  978         error = (*so->so_receive)(so, from, &auio, NULL, control,
  979             &mp->msg_flags);
  980         KASSERT(*from == NULL || (*from)->m_next == NULL);
  981         len -= auio.uio_resid;
  982         *retsize = len;
  983         if (error != 0 && len != 0
  984             && (error == ERESTART || error == EINTR || error == EWOULDBLOCK))
  985                 /* Some data transferred */
  986                 error = 0;
  987 
  988         if (ktriov != NULL) {
  989                 ktrgeniov(s, UIO_READ, ktriov, len, error);
  990                 kmem_free(ktriov, iovsz);
  991         }
  992 
  993         if (error != 0) {
  994                 m_freem(*from);
  995                 *from = NULL;
  996                 if (control != NULL) {
  997                         free_control_mbuf(l, *control, *control);
  998                         *control = NULL;
  999                 }
 1000         }
 1001  out:
 1002         if (iov != aiov)
 1003                 kmem_free(iov, iovsz);
 1004         return error;
 1005 }
 1006 
 1007 
 1008 int
 1009 do_sys_recvmsg(struct lwp *l, int s, struct msghdr *mp,
 1010     struct mbuf **from, struct mbuf **control, register_t *retsize)
 1011 {
 1012         int error;
 1013         struct socket *so;
 1014 
 1015         if ((error = fd_getsock(s, &so)) != 0)
 1016                 return error;
 1017         error = do_sys_recvmsg_so(l, s, so, mp, from, control, retsize);
 1018         fd_putfile(s);
 1019         return error;
 1020 }
 1021 
 1022 int
 1023 sys_recvmmsg(struct lwp *l, const struct sys_recvmmsg_args *uap,
 1024     register_t *retval)
 1025 {
 1026         /* {
 1027                 syscallarg(int)                 s;
 1028                 syscallarg(struct mmsghdr *)    mmsg;
 1029                 syscallarg(unsigned int)        vlen;
 1030                 syscallarg(unsigned int)        flags;
 1031                 syscallarg(struct timespec *)   timeout;
 1032         } */
 1033         struct mmsghdr mmsg;
 1034         struct socket *so;
 1035         struct msghdr *msg = &mmsg.msg_hdr;
 1036         int error, s;
 1037         struct mbuf *from, *control;
 1038         struct timespec ts, now;
 1039         unsigned int vlen, flags, dg;
 1040 
 1041         if (SCARG(uap, timeout)) {
 1042                 if ((error = copyin(SCARG(uap, timeout), &ts, sizeof(ts))) != 0)
 1043                         return error;
 1044                 if (ts.tv_nsec < 0 || ts.tv_nsec >= 1000000000L)
 1045                         return EINVAL;
 1046                 getnanotime(&now);
 1047                 if (timespecaddok(&now, &ts)) {
 1048                         timespecadd(&now, &ts, &ts);
 1049                 } else {
 1050                         ts.tv_sec = __type_max(time_t);
 1051                         ts.tv_nsec = 999999999L;
 1052                 }
 1053         }
 1054 
 1055         s = SCARG(uap, s);
 1056         if ((error = fd_getsock(s, &so)) != 0)
 1057                 return error;
 1058 
 1059         /*
 1060          * If so->so_rerror holds a deferred error return it now.
 1061          */
 1062         if (so->so_rerror) {
 1063                 error = so->so_rerror;
 1064                 so->so_rerror = 0;
 1065                 fd_putfile(s);
 1066                 return error;
 1067         }
 1068 
 1069         vlen = SCARG(uap, vlen);
 1070         if (vlen > 1024)
 1071                 vlen = 1024;
 1072 
 1073         from = NULL;
 1074         flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE;
 1075 
 1076         for (dg = 0; dg < vlen;) {
 1077                 error = copyin(SCARG(uap, mmsg) + dg, &mmsg, sizeof(mmsg));
 1078                 if (error)
 1079                         break;
 1080 
 1081                 msg->msg_flags = flags & ~MSG_WAITFORONE;
 1082 
 1083                 if (from != NULL) {
 1084                         m_free(from);
 1085                         from = NULL;
 1086                 }
 1087 
 1088                 error = do_sys_recvmsg_so(l, s, so, msg, &from,
 1089                     msg->msg_control != NULL ? &control : NULL, retval);
 1090                 if (error) {
 1091                         if (error == EAGAIN && dg > 0)
 1092                                 error = 0;
 1093                         break;
 1094                 }
 1095 
 1096                 if (msg->msg_control != NULL)
 1097                         error = copyout_msg_control(l, msg, control);
 1098                 if (error)
 1099                         break;
 1100 
 1101                 error = copyout_sockname(msg->msg_name, &msg->msg_namelen, 0,
 1102                     from);
 1103                 if (error)
 1104                         break;
 1105 
 1106                 ktrkuser("msghdr", msg, sizeof *msg);
 1107                 mmsg.msg_len = *retval;
 1108 
 1109                 error = copyout(&mmsg, SCARG(uap, mmsg) + dg, sizeof(mmsg));
 1110                 if (error)
 1111                         break;
 1112 
 1113                 dg++;
 1114                 if (msg->msg_flags & MSG_OOB)
 1115                         break;
 1116 
 1117                 if (SCARG(uap, timeout)) {
 1118                         getnanotime(&now);
 1119                         if (timespeccmp(&ts, &now, <))
 1120                                 break;
 1121                 }
 1122 
 1123                 if (flags & MSG_WAITFORONE)
 1124                         flags |= MSG_DONTWAIT;
 1125 
 1126         }
 1127 
 1128         if (from != NULL)
 1129                 m_free(from);
 1130 
 1131         *retval = dg;
 1132 
 1133         /*
 1134          * If we succeeded at least once, return 0, hopefully so->so_rerror
 1135          * will catch it next time.
 1136          */
 1137         if (error && dg > 0) {
 1138                 so->so_rerror = error;
 1139                 error = 0;
 1140         }
 1141 
 1142         fd_putfile(s);
 1143 
 1144         return error;
 1145 }
 1146 
 1147 int
 1148 sys_shutdown(struct lwp *l, const struct sys_shutdown_args *uap,
 1149     register_t *retval)
 1150 {
 1151         /* {
 1152                 syscallarg(int) s;
 1153                 syscallarg(int) how;
 1154         } */
 1155         struct socket   *so;
 1156         int             error;
 1157 
 1158         if ((error = fd_getsock(SCARG(uap, s), &so)) != 0)
 1159                 return error;
 1160         solock(so);
 1161         error = soshutdown(so, SCARG(uap, how));
 1162         sounlock(so);
 1163         fd_putfile(SCARG(uap, s));
 1164         return error;
 1165 }
 1166 
 1167 int
 1168 sys_setsockopt(struct lwp *l, const struct sys_setsockopt_args *uap,
 1169     register_t *retval)
 1170 {
 1171         /* {
 1172                 syscallarg(int)                 s;
 1173                 syscallarg(int)                 level;
 1174                 syscallarg(int)                 name;
 1175                 syscallarg(const void *)        val;
 1176                 syscallarg(unsigned int)        valsize;
 1177         } */
 1178         struct sockopt  sopt;
 1179         struct socket   *so;
 1180         file_t          *fp;
 1181         int             error;
 1182         unsigned int    len;
 1183 
 1184         len = SCARG(uap, valsize);
 1185         if (len > 0 && SCARG(uap, val) == NULL)
 1186                 return EINVAL;
 1187 
 1188         if (len > MCLBYTES)
 1189                 return EINVAL;
 1190 
 1191         if ((error = fd_getsock1(SCARG(uap, s), &so, &fp)) != 0)
 1192                 return (error);
 1193 
 1194         sockopt_init(&sopt, SCARG(uap, level), SCARG(uap, name), len);
 1195 
 1196         if (len > 0) {
 1197                 error = copyin(SCARG(uap, val), sopt.sopt_data, len);
 1198                 if (error)
 1199                         goto out;
 1200         }
 1201 
 1202         error = sosetopt(so, &sopt);
 1203         if (so->so_options & SO_NOSIGPIPE)
 1204                 atomic_or_uint(&fp->f_flag, FNOSIGPIPE);
 1205         else
 1206                 atomic_and_uint(&fp->f_flag, ~FNOSIGPIPE);
 1207 
 1208  out:
 1209         sockopt_destroy(&sopt);
 1210         fd_putfile(SCARG(uap, s));
 1211         return error;
 1212 }
 1213 
 1214 static int
 1215 getsockopt(struct lwp *l, const struct sys_getsockopt_args *uap,
 1216     register_t *retval, bool copyarg)
 1217 {
 1218         struct sockopt  sopt;
 1219         struct socket   *so;
 1220         file_t          *fp;
 1221         unsigned int    valsize, len;
 1222         int             error;
 1223 
 1224         if (SCARG(uap, val) != NULL) {
 1225                 error = copyin(SCARG(uap, avalsize), &valsize, sizeof(valsize));
 1226                 if (error)
 1227                         return error;
 1228         } else
 1229                 valsize = 0;
 1230 
 1231         if (valsize > MCLBYTES)
 1232                 return EINVAL;
 1233 
 1234         if ((error = fd_getsock1(SCARG(uap, s), &so, &fp)) != 0)
 1235                 return error;
 1236 
 1237         sockopt_init(&sopt, SCARG(uap, level), SCARG(uap, name), valsize);
 1238         if (copyarg && valsize > 0) {
 1239                 error = copyin(SCARG(uap, val), sopt.sopt_data, valsize);
 1240                 if (error)
 1241                         goto out;
 1242         }
 1243 
 1244         if (fp->f_flag & FNOSIGPIPE)
 1245                 so->so_options |= SO_NOSIGPIPE;
 1246         else
 1247                 so->so_options &= ~SO_NOSIGPIPE;
 1248 
 1249         error = sogetopt(so, &sopt);
 1250         if (error || valsize == 0)
 1251                 goto out;
 1252 
 1253         len = uimin(valsize, sopt.sopt_retsize);
 1254         error = copyout(sopt.sopt_data, SCARG(uap, val), len);
 1255         if (error)
 1256                 goto out;
 1257 
 1258         error = copyout(&len, SCARG(uap, avalsize), sizeof(len));
 1259  out:
 1260         sockopt_destroy(&sopt);
 1261         fd_putfile(SCARG(uap, s));
 1262         return error;
 1263 }
 1264 
 1265 int
 1266 sys_getsockopt(struct lwp *l, const struct sys_getsockopt_args *uap,
 1267     register_t *retval)
 1268 {
 1269         /* {
 1270                 syscallarg(int)                 s;
 1271                 syscallarg(int)                 level;
 1272                 syscallarg(int)                 name;
 1273                 syscallarg(void *)              val;
 1274                 syscallarg(unsigned int *)      avalsize;
 1275         } */
 1276         return getsockopt(l, uap, retval, false);
 1277 }
 1278 
 1279 int
 1280 sys_getsockopt2(struct lwp *l, const struct sys_getsockopt2_args *uap,
 1281     register_t *retval)
 1282 {
 1283         /* {
 1284                 syscallarg(int)                 s;
 1285                 syscallarg(int)                 level;
 1286                 syscallarg(int)                 name;
 1287                 syscallarg(void *)              val;
 1288                 syscallarg(unsigned int *)      avalsize;
 1289         } */
 1290         return getsockopt(l, (const struct sys_getsockopt_args *) uap, retval, true);
 1291 }
 1292 
 1293 #ifdef PIPE_SOCKETPAIR
 1294 
 1295 int
 1296 pipe1(struct lwp *l, int *fildes, int flags)
 1297 {
 1298         file_t          *rf, *wf;
 1299         struct socket   *rso, *wso;
 1300         int             fd, error;
 1301         proc_t          *p;
 1302 
 1303         if (flags & ~(O_CLOEXEC|O_NONBLOCK|O_NOSIGPIPE))
 1304                 return EINVAL;
 1305         p = curproc;
 1306         if ((error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, l, NULL)) != 0)
 1307                 return error;
 1308         if ((error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, l, rso)) != 0)
 1309                 goto free1;
 1310         /* remember this socket pair implements a pipe */
 1311         wso->so_state |= SS_ISAPIPE;
 1312         rso->so_state |= SS_ISAPIPE;
 1313         if ((error = fd_allocfile(&rf, &fd)) != 0)
 1314                 goto free2;
 1315         fildes[0] = fd;
 1316         rf->f_flag = FREAD | flags;
 1317         rf->f_type = DTYPE_SOCKET;
 1318         rf->f_ops = &socketops;
 1319         rf->f_socket = rso;
 1320         if ((error = fd_allocfile(&wf, &fd)) != 0)
 1321                 goto free3;
 1322         wf->f_flag = FWRITE | flags;
 1323         wf->f_type = DTYPE_SOCKET;
 1324         wf->f_ops = &socketops;
 1325         wf->f_socket = wso;
 1326         fildes[1] = fd;
 1327         solock(wso);
 1328         /*
 1329          * Pipes must be readable when there is at least 1
 1330          * byte of data available in the receive buffer.
 1331          *
 1332          * Pipes must be writable when there is space for
 1333          * at least PIPE_BUF bytes in the send buffer.
 1334          * If we're increasing the low water mark for the
 1335          * send buffer, then mimic how soreserve() would
 1336          * have set the high water mark.
 1337          */
 1338         rso->so_rcv.sb_lowat = 1;
 1339         if (wso->so_snd.sb_lowat < PIPE_BUF) {
 1340                 wso->so_snd.sb_hiwat = PIPE_BUF * 2;
 1341         }
 1342         wso->so_snd.sb_lowat = PIPE_BUF;
 1343         error = unp_connect2(wso, rso);
 1344         sounlock(wso);
 1345         if (error != 0)
 1346                 goto free4;
 1347         fd_affix(p, wf, fildes[1]);
 1348         fd_affix(p, rf, fildes[0]);
 1349         return (0);
 1350  free4:
 1351         fd_abort(p, wf, fildes[1]);
 1352  free3:
 1353         fd_abort(p, rf, fildes[0]);
 1354  free2:
 1355         (void)soclose(wso);
 1356  free1:
 1357         (void)soclose(rso);
 1358         return error;
 1359 }
 1360 #endif /* PIPE_SOCKETPAIR */
 1361 
 1362 /*
 1363  * Get peer socket name.
 1364  */
 1365 int
 1366 do_sys_getpeername(int fd, struct sockaddr *nam)
 1367 {
 1368         struct socket   *so;
 1369         int             error;
 1370 
 1371         if ((error = fd_getsock(fd, &so)) != 0)
 1372                 return error;
 1373 
 1374         solock(so);
 1375         if ((so->so_state & SS_ISCONNECTED) == 0)
 1376                 error = ENOTCONN;
 1377         else {
 1378                 error = (*so->so_proto->pr_usrreqs->pr_peeraddr)(so, nam);
 1379         }
 1380         sounlock(so);
 1381         fd_putfile(fd);
 1382         return error;
 1383 }
 1384 
 1385 /*
 1386  * Get local socket name.
 1387  */
 1388 int
 1389 do_sys_getsockname(int fd, struct sockaddr *nam)
 1390 {
 1391         struct socket   *so;
 1392         int             error;
 1393 
 1394         if ((error = fd_getsock(fd, &so)) != 0)
 1395                 return error;
 1396 
 1397         solock(so);
 1398         error = (*so->so_proto->pr_usrreqs->pr_sockaddr)(so, nam);
 1399         sounlock(so);
 1400         fd_putfile(fd);
 1401         return error;
 1402 }
 1403 
 1404 int
 1405 copyout_sockname_sb(struct sockaddr *asa, unsigned int *alen, int flags,
 1406     struct sockaddr_big *addr)
 1407 {
 1408         unsigned int len;
 1409         int error;
 1410 
 1411         if (asa == NULL)
 1412                 /* Assume application not interested */
 1413                 return 0;
 1414 
 1415         if (flags & MSG_LENUSRSPACE) {
 1416                 error = copyin(alen, &len, sizeof(len));
 1417                 if (error)
 1418                         return error;
 1419         } else
 1420                 len = *alen;
 1421 
 1422         if (addr == NULL) {
 1423                 len = 0;
 1424                 error = 0;
 1425         } else {
 1426                 if (len > addr->sb_len)
 1427                         len = addr->sb_len;
 1428                 /* XXX addr isn't an mbuf... */
 1429                 ktrkuser(mbuftypes[MT_SONAME], addr, len);
 1430                 error = copyout(addr, asa, len);
 1431         }
 1432 
 1433         if (error == 0) {
 1434                 if (flags & MSG_LENUSRSPACE)
 1435                         error = copyout(&len, alen, sizeof(len));
 1436                 else
 1437                         *alen = len;
 1438         }
 1439 
 1440         return error;
 1441 }
 1442 
 1443 int
 1444 copyout_sockname(struct sockaddr *asa, unsigned int *alen, int flags,
 1445     struct mbuf *addr)
 1446 {
 1447         int len;
 1448         int error;
 1449 
 1450         if (asa == NULL)
 1451                 /* Assume application not interested */
 1452                 return 0;
 1453 
 1454         if (flags & MSG_LENUSRSPACE) {
 1455                 error = copyin(alen, &len, sizeof(len));
 1456                 if (error)
 1457                         return error;
 1458         } else
 1459                 len = *alen;
 1460         if (len < 0)
 1461                 return EINVAL;
 1462 
 1463         if (addr == NULL) {
 1464                 len = 0;
 1465                 error = 0;
 1466         } else {
 1467                 if (len > addr->m_len)
 1468                         len = addr->m_len;
 1469                 /* Maybe this ought to copy a chain ? */
 1470                 ktrkuser(mbuftypes[MT_SONAME], mtod(addr, void *), len);
 1471                 error = copyout(mtod(addr, void *), asa, len);
 1472         }
 1473 
 1474         if (error == 0) {
 1475                 if (flags & MSG_LENUSRSPACE)
 1476                         error = copyout(&len, alen, sizeof(len));
 1477                 else
 1478                         *alen = len;
 1479         }
 1480 
 1481         return error;
 1482 }
 1483 
 1484 /*
 1485  * Get socket name.
 1486  */
 1487 int
 1488 sys_getsockname(struct lwp *l, const struct sys_getsockname_args *uap,
 1489     register_t *retval)
 1490 {
 1491         /* {
 1492                 syscallarg(int)                 fdes;
 1493                 syscallarg(struct sockaddr *)   asa;
 1494                 syscallarg(unsigned int *)      alen;
 1495         } */
 1496         struct sockaddr_big sbig;
 1497         int                 error;
 1498 
 1499         sbig.sb_len = UCHAR_MAX;
 1500         error = do_sys_getsockname(SCARG(uap, fdes), (struct sockaddr *)&sbig);
 1501         if (error != 0)
 1502                 return error;
 1503 
 1504         error = copyout_sockname_sb(SCARG(uap, asa), SCARG(uap, alen),
 1505             MSG_LENUSRSPACE, &sbig);
 1506         return error;
 1507 }
 1508 
 1509 /*
 1510  * Get name of peer for connected socket.
 1511  */
 1512 int
 1513 sys_getpeername(struct lwp *l, const struct sys_getpeername_args *uap,
 1514     register_t *retval)
 1515 {
 1516         /* {
 1517                 syscallarg(int)                 fdes;
 1518                 syscallarg(struct sockaddr *)   asa;
 1519                 syscallarg(unsigned int *)      alen;
 1520         } */
 1521         struct sockaddr_big sbig;
 1522         int                 error;
 1523 
 1524         sbig.sb_len = UCHAR_MAX;
 1525         error = do_sys_getpeername(SCARG(uap, fdes), (struct sockaddr *)&sbig);
 1526         if (error != 0)
 1527                 return error;
 1528 
 1529         error = copyout_sockname_sb(SCARG(uap, asa), SCARG(uap, alen),
 1530             MSG_LENUSRSPACE, &sbig);
 1531         return error;
 1532 }
 1533 
 1534 static int
 1535 sockargs_sb(struct sockaddr_big *sb, const void *name, socklen_t buflen)
 1536 {
 1537         int error;
 1538 
 1539         /*
 1540          * We can't allow socket names > UCHAR_MAX in length, since that
 1541          * will overflow sb_len. Further no reasonable buflen is <=
 1542          * offsetof(sockaddr_big, sb_data) since it shall be at least
 1543          * the size of the preamble sb_len and sb_family members.
 1544          */
 1545         if (buflen > UCHAR_MAX ||
 1546             buflen <= offsetof(struct sockaddr_big, sb_data))
 1547                 return EINVAL;
 1548 
 1549         error = copyin(name, (void *)sb, buflen);
 1550         if (error)
 1551                 return error;
 1552 
 1553         ktrkuser(mbuftypes[MT_SONAME], sb, buflen);
 1554 #if BYTE_ORDER != BIG_ENDIAN
 1555         /*
 1556          * 4.3BSD compat thing - need to stay, since bind(2),
 1557          * connect(2), sendto(2) were not versioned for COMPAT_43.
 1558          */
 1559         if (sb->sb_family == 0 && sb->sb_len < AF_MAX)
 1560                 sb->sb_family = sb->sb_len;
 1561 #endif
 1562         sb->sb_len = buflen;
 1563         return 0;
 1564 }
 1565 
 1566 /*
 1567  * XXX In a perfect world, we wouldn't pass around socket control
 1568  * XXX arguments in mbufs, and this could go away.
 1569  */
 1570 int
 1571 sockargs(struct mbuf **mp, const void *bf, size_t buflen, enum uio_seg seg,
 1572     int type)
 1573 {
 1574         struct mbuf     *m;
 1575         int             error;
 1576 
 1577         /*
 1578          * We can't allow socket names > UCHAR_MAX in length, since that
 1579          * will overflow sa_len.  Control data more than a page size in
 1580          * length is just too much.
 1581          */
 1582         if (buflen > (type == MT_SONAME ? UCHAR_MAX : PAGE_SIZE))
 1583                 return EINVAL;
 1584 
 1585         /*
 1586          * length must greater than sizeof(sa_family) + sizeof(sa_len)
 1587          */
 1588         if (type == MT_SONAME && buflen <= 2)
 1589                 return EINVAL;
 1590 
 1591         /* Allocate an mbuf to hold the arguments. */
 1592         m = m_get(M_WAIT, type);
 1593         /* can't claim.  don't who to assign it to. */
 1594         if (buflen > MLEN) {
 1595                 /*
 1596                  * Won't fit into a regular mbuf, so we allocate just
 1597                  * enough external storage to hold the argument.
 1598                  */
 1599                 MEXTMALLOC(m, buflen, M_WAITOK);
 1600         }
 1601         m->m_len = buflen;
 1602         if (seg == UIO_USERSPACE) {
 1603                 error = copyin(bf, mtod(m, void *), buflen);
 1604                 if (error) {
 1605                         (void)m_free(m);
 1606                         return error;
 1607                 }
 1608         } else {
 1609                 memcpy(mtod(m, void *), bf, buflen);
 1610         }
 1611         *mp = m;
 1612         switch (type) {
 1613         case MT_SONAME:
 1614                 ktrkuser(mbuftypes[type], mtod(m, void *), buflen);
 1615 
 1616                 struct sockaddr *sa = mtod(m, struct sockaddr *);
 1617 #if BYTE_ORDER != BIG_ENDIAN
 1618                 /*
 1619                  * 4.3BSD compat thing - need to stay, since bind(2),
 1620                  * connect(2), sendto(2) were not versioned for COMPAT_43.
 1621                  */
 1622                 if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
 1623                         sa->sa_family = sa->sa_len;
 1624 #endif
 1625                 sa->sa_len = buflen;
 1626                 return 0;
 1627         case MT_CONTROL:
 1628                 if (!KTRPOINT(curproc, KTR_USER))
 1629                         return 0;
 1630 
 1631                 struct msghdr mhdr;
 1632                 mhdr.msg_control = mtod(m, void *);
 1633                 mhdr.msg_controllen = buflen;
 1634                 for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mhdr); cmsg;
 1635                     cmsg = CMSG_NXTHDR(&mhdr, cmsg)) {
 1636                         KASSERT(((char *)cmsg - mtod(m, char *)) <= buflen);
 1637                         if (cmsg->cmsg_len >
 1638                             buflen - ((char *)cmsg - mtod(m, char *)))
 1639                                 break;
 1640                         ktrkuser(mbuftypes[type], cmsg, cmsg->cmsg_len);
 1641                 }
 1642                 return 0;
 1643         default:
 1644                 return EINVAL;
 1645         }
 1646 }
 1647 
 1648 int
 1649 do_sys_peeloff(struct socket *head, void *data)
 1650 {
 1651 #ifdef SCTP
 1652         /*file_t *lfp = NULL;*/
 1653         file_t *nfp = NULL;
 1654         int error;
 1655         struct socket *so;
 1656         int fd;
 1657         uint32_t name;
 1658         /*short fflag;*/                /* type must match fp->f_flag */
 1659 
 1660         name = *(uint32_t *) data;
 1661         error = sctp_can_peel_off(head, name);
 1662         if (error) {
 1663                 printf("peeloff failed\n");
 1664                 return error;
 1665         }
 1666         /*
 1667          * At this point we know we do have a assoc to pull
 1668          * we proceed to get the fd setup. This may block
 1669          * but that is ok.
 1670          */
 1671         error = fd_allocfile(&nfp, &fd);
 1672         if (error) {
 1673                 /*
 1674                  * Probably ran out of file descriptors. Put the
 1675                  * unaccepted connection back onto the queue and
 1676                  * do another wakeup so some other process might
 1677                  * have a chance at it.
 1678                  */
 1679                 return error;
 1680         }
 1681         *(int *) data = fd;
 1682 
 1683         so = sctp_get_peeloff(head, name, &error);
 1684         if (so == NULL) {
 1685                 /*
 1686                  * Either someone else peeled it off OR
 1687                  * we can't get a socket.
 1688                  * close the new descriptor, assuming someone hasn't ripped it
 1689                  * out from under us.
 1690                  */
 1691                 mutex_enter(&nfp->f_lock);
 1692                 nfp->f_count++;
 1693                 mutex_exit(&nfp->f_lock);
 1694                 fd_abort(curlwp->l_proc, nfp, fd);
 1695                 return error;
 1696         }
 1697         so->so_state &= ~SS_NOFDREF;
 1698         so->so_state &= ~SS_ISCONNECTING;
 1699         so->so_head = NULL;
 1700         so->so_cred = kauth_cred_dup(head->so_cred);
 1701         nfp->f_socket = so;
 1702         nfp->f_flag = FREAD|FWRITE;
 1703         nfp->f_ops = &socketops;
 1704         nfp->f_type = DTYPE_SOCKET;
 1705 
 1706         fd_affix(curlwp->l_proc, nfp, fd);
 1707 
 1708         return error;
 1709 #else
 1710         return EOPNOTSUPP;
 1711 #endif
 1712 }

Cache object: c4fce0ca3a285451769fe2e2426a7de7


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.