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 /*-
    2  * Copyright (c) 1982, 1986, 1989, 1990, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 4. Neither the name of the University nor the names of its contributors
   14  *    may be used to endorse or promote products derived from this software
   15  *    without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  *      @(#)uipc_syscalls.c     8.4 (Berkeley) 2/21/94
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD: releng/11.1/sys/kern/uipc_syscalls.c 315549 2017-03-19 14:25:23Z trasz $");
   34 
   35 #include "opt_capsicum.h"
   36 #include "opt_inet.h"
   37 #include "opt_inet6.h"
   38 #include "opt_compat.h"
   39 #include "opt_ktrace.h"
   40 
   41 #include <sys/param.h>
   42 #include <sys/systm.h>
   43 #include <sys/capsicum.h>
   44 #include <sys/kernel.h>
   45 #include <sys/lock.h>
   46 #include <sys/mutex.h>
   47 #include <sys/sysproto.h>
   48 #include <sys/malloc.h>
   49 #include <sys/filedesc.h>
   50 #include <sys/proc.h>
   51 #include <sys/filio.h>
   52 #include <sys/jail.h>
   53 #include <sys/mbuf.h>
   54 #include <sys/protosw.h>
   55 #include <sys/rwlock.h>
   56 #include <sys/socket.h>
   57 #include <sys/socketvar.h>
   58 #include <sys/syscallsubr.h>
   59 #ifdef KTRACE
   60 #include <sys/ktrace.h>
   61 #endif
   62 #ifdef COMPAT_FREEBSD32
   63 #include <compat/freebsd32/freebsd32_util.h>
   64 #endif
   65 
   66 #include <net/vnet.h>
   67 
   68 #include <security/audit/audit.h>
   69 #include <security/mac/mac_framework.h>
   70 
   71 /*
   72  * Flags for accept1() and kern_accept4(), in addition to SOCK_CLOEXEC
   73  * and SOCK_NONBLOCK.
   74  */
   75 #define ACCEPT4_INHERIT 0x1
   76 #define ACCEPT4_COMPAT  0x2
   77 
   78 static int sendit(struct thread *td, int s, struct msghdr *mp, int flags);
   79 static int recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp);
   80 
   81 static int accept1(struct thread *td, int s, struct sockaddr *uname,
   82                    socklen_t *anamelen, int flags);
   83 static int getsockname1(struct thread *td, struct getsockname_args *uap,
   84                         int compat);
   85 static int getpeername1(struct thread *td, struct getpeername_args *uap,
   86                         int compat);
   87 static int sockargs(struct mbuf **, char *, socklen_t, int);
   88 
   89 /*
   90  * Convert a user file descriptor to a kernel file entry and check if required
   91  * capability rights are present.
   92  * If required copy of current set of capability rights is returned.
   93  * A reference on the file entry is held upon returning.
   94  */
   95 int
   96 getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
   97     struct file **fpp, u_int *fflagp, struct filecaps *havecapsp)
   98 {
   99         struct file *fp;
  100         int error;
  101 
  102         error = fget_cap(td, fd, rightsp, &fp, havecapsp);
  103         if (error != 0)
  104                 return (error);
  105         if (fp->f_type != DTYPE_SOCKET) {
  106                 fdrop(fp, td);
  107                 if (havecapsp != NULL)
  108                         filecaps_free(havecapsp);
  109                 return (ENOTSOCK);
  110         }
  111         if (fflagp != NULL)
  112                 *fflagp = fp->f_flag;
  113         *fpp = fp;
  114         return (0);
  115 }
  116 
  117 /*
  118  * System call interface to the socket abstraction.
  119  */
  120 #if defined(COMPAT_43)
  121 #define COMPAT_OLDSOCK
  122 #endif
  123 
  124 int
  125 sys_socket(td, uap)
  126         struct thread *td;
  127         struct socket_args /* {
  128                 int     domain;
  129                 int     type;
  130                 int     protocol;
  131         } */ *uap;
  132 {
  133 
  134         return (kern_socket(td, uap->domain, uap->type, uap->protocol));
  135 }
  136 
  137 int
  138 kern_socket(struct thread *td, int domain, int type, int protocol)
  139 {
  140         struct socket *so;
  141         struct file *fp;
  142         int fd, error, oflag, fflag;
  143 
  144         AUDIT_ARG_SOCKET(domain, type, protocol);
  145 
  146         oflag = 0;
  147         fflag = 0;
  148         if ((type & SOCK_CLOEXEC) != 0) {
  149                 type &= ~SOCK_CLOEXEC;
  150                 oflag |= O_CLOEXEC;
  151         }
  152         if ((type & SOCK_NONBLOCK) != 0) {
  153                 type &= ~SOCK_NONBLOCK;
  154                 fflag |= FNONBLOCK;
  155         }
  156 
  157 #ifdef MAC
  158         error = mac_socket_check_create(td->td_ucred, domain, type, protocol);
  159         if (error != 0)
  160                 return (error);
  161 #endif
  162         error = falloc(td, &fp, &fd, oflag);
  163         if (error != 0)
  164                 return (error);
  165         /* An extra reference on `fp' has been held for us by falloc(). */
  166         error = socreate(domain, &so, type, protocol, td->td_ucred, td);
  167         if (error != 0) {
  168                 fdclose(td, fp, fd);
  169         } else {
  170                 finit(fp, FREAD | FWRITE | fflag, DTYPE_SOCKET, so, &socketops);
  171                 if ((fflag & FNONBLOCK) != 0)
  172                         (void) fo_ioctl(fp, FIONBIO, &fflag, td->td_ucred, td);
  173                 td->td_retval[0] = fd;
  174         }
  175         fdrop(fp, td);
  176         return (error);
  177 }
  178 
  179 /* ARGSUSED */
  180 int
  181 sys_bind(td, uap)
  182         struct thread *td;
  183         struct bind_args /* {
  184                 int     s;
  185                 caddr_t name;
  186                 int     namelen;
  187         } */ *uap;
  188 {
  189         struct sockaddr *sa;
  190         int error;
  191 
  192         error = getsockaddr(&sa, uap->name, uap->namelen);
  193         if (error == 0) {
  194                 error = kern_bindat(td, AT_FDCWD, uap->s, sa);
  195                 free(sa, M_SONAME);
  196         }
  197         return (error);
  198 }
  199 
  200 int
  201 kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
  202 {
  203         struct socket *so;
  204         struct file *fp;
  205         cap_rights_t rights;
  206         int error;
  207 
  208         AUDIT_ARG_FD(fd);
  209         AUDIT_ARG_SOCKADDR(td, dirfd, sa);
  210         error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_BIND),
  211             &fp, NULL, NULL);
  212         if (error != 0)
  213                 return (error);
  214         so = fp->f_data;
  215 #ifdef KTRACE
  216         if (KTRPOINT(td, KTR_STRUCT))
  217                 ktrsockaddr(sa);
  218 #endif
  219 #ifdef MAC
  220         error = mac_socket_check_bind(td->td_ucred, so, sa);
  221         if (error == 0) {
  222 #endif
  223                 if (dirfd == AT_FDCWD)
  224                         error = sobind(so, sa, td);
  225                 else
  226                         error = sobindat(dirfd, so, sa, td);
  227 #ifdef MAC
  228         }
  229 #endif
  230         fdrop(fp, td);
  231         return (error);
  232 }
  233 
  234 /* ARGSUSED */
  235 int
  236 sys_bindat(td, uap)
  237         struct thread *td;
  238         struct bindat_args /* {
  239                 int     fd;
  240                 int     s;
  241                 caddr_t name;
  242                 int     namelen;
  243         } */ *uap;
  244 {
  245         struct sockaddr *sa;
  246         int error;
  247 
  248         error = getsockaddr(&sa, uap->name, uap->namelen);
  249         if (error == 0) {
  250                 error = kern_bindat(td, uap->fd, uap->s, sa);
  251                 free(sa, M_SONAME);
  252         }
  253         return (error);
  254 }
  255 
  256 /* ARGSUSED */
  257 int
  258 sys_listen(td, uap)
  259         struct thread *td;
  260         struct listen_args /* {
  261                 int     s;
  262                 int     backlog;
  263         } */ *uap;
  264 {
  265 
  266         return (kern_listen(td, uap->s, uap->backlog));
  267 }
  268 
  269 int
  270 kern_listen(struct thread *td, int s, int backlog)
  271 {
  272         struct socket *so;
  273         struct file *fp;
  274         cap_rights_t rights;
  275         int error;
  276 
  277         AUDIT_ARG_FD(s);
  278         error = getsock_cap(td, s, cap_rights_init(&rights, CAP_LISTEN),
  279             &fp, NULL, NULL);
  280         if (error == 0) {
  281                 so = fp->f_data;
  282 #ifdef MAC
  283                 error = mac_socket_check_listen(td->td_ucred, so);
  284                 if (error == 0)
  285 #endif
  286                         error = solisten(so, backlog, td);
  287                 fdrop(fp, td);
  288         }
  289         return (error);
  290 }
  291 
  292 /*
  293  * accept1()
  294  */
  295 static int
  296 accept1(td, s, uname, anamelen, flags)
  297         struct thread *td;
  298         int s;
  299         struct sockaddr *uname;
  300         socklen_t *anamelen;
  301         int flags;
  302 {
  303         struct sockaddr *name;
  304         socklen_t namelen;
  305         struct file *fp;
  306         int error;
  307 
  308         if (uname == NULL)
  309                 return (kern_accept4(td, s, NULL, NULL, flags, NULL));
  310 
  311         error = copyin(anamelen, &namelen, sizeof (namelen));
  312         if (error != 0)
  313                 return (error);
  314 
  315         error = kern_accept4(td, s, &name, &namelen, flags, &fp);
  316 
  317         if (error != 0)
  318                 return (error);
  319 
  320         if (error == 0 && uname != NULL) {
  321 #ifdef COMPAT_OLDSOCK
  322                 if (flags & ACCEPT4_COMPAT)
  323                         ((struct osockaddr *)name)->sa_family =
  324                             name->sa_family;
  325 #endif
  326                 error = copyout(name, uname, namelen);
  327         }
  328         if (error == 0)
  329                 error = copyout(&namelen, anamelen,
  330                     sizeof(namelen));
  331         if (error != 0)
  332                 fdclose(td, fp, td->td_retval[0]);
  333         fdrop(fp, td);
  334         free(name, M_SONAME);
  335         return (error);
  336 }
  337 
  338 int
  339 kern_accept(struct thread *td, int s, struct sockaddr **name,
  340     socklen_t *namelen, struct file **fp)
  341 {
  342         return (kern_accept4(td, s, name, namelen, ACCEPT4_INHERIT, fp));
  343 }
  344 
  345 int
  346 kern_accept4(struct thread *td, int s, struct sockaddr **name,
  347     socklen_t *namelen, int flags, struct file **fp)
  348 {
  349         struct file *headfp, *nfp = NULL;
  350         struct sockaddr *sa = NULL;
  351         struct socket *head, *so;
  352         struct filecaps fcaps;
  353         cap_rights_t rights;
  354         u_int fflag;
  355         pid_t pgid;
  356         int error, fd, tmp;
  357 
  358         if (name != NULL)
  359                 *name = NULL;
  360 
  361         AUDIT_ARG_FD(s);
  362         error = getsock_cap(td, s, cap_rights_init(&rights, CAP_ACCEPT),
  363             &headfp, &fflag, &fcaps);
  364         if (error != 0)
  365                 return (error);
  366         head = headfp->f_data;
  367         if ((head->so_options & SO_ACCEPTCONN) == 0) {
  368                 error = EINVAL;
  369                 goto done;
  370         }
  371 #ifdef MAC
  372         error = mac_socket_check_accept(td->td_ucred, head);
  373         if (error != 0)
  374                 goto done;
  375 #endif
  376         error = falloc_caps(td, &nfp, &fd,
  377             (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0, &fcaps);
  378         if (error != 0)
  379                 goto done;
  380         ACCEPT_LOCK();
  381         if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->so_comp)) {
  382                 ACCEPT_UNLOCK();
  383                 error = EWOULDBLOCK;
  384                 goto noconnection;
  385         }
  386         while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) {
  387                 if (head->so_rcv.sb_state & SBS_CANTRCVMORE) {
  388                         head->so_error = ECONNABORTED;
  389                         break;
  390                 }
  391                 error = msleep(&head->so_timeo, &accept_mtx, PSOCK | PCATCH,
  392                     "accept", 0);
  393                 if (error != 0) {
  394                         ACCEPT_UNLOCK();
  395                         goto noconnection;
  396                 }
  397         }
  398         if (head->so_error) {
  399                 error = head->so_error;
  400                 head->so_error = 0;
  401                 ACCEPT_UNLOCK();
  402                 goto noconnection;
  403         }
  404         so = TAILQ_FIRST(&head->so_comp);
  405         KASSERT(!(so->so_qstate & SQ_INCOMP), ("accept1: so SQ_INCOMP"));
  406         KASSERT(so->so_qstate & SQ_COMP, ("accept1: so not SQ_COMP"));
  407 
  408         /*
  409          * Before changing the flags on the socket, we have to bump the
  410          * reference count.  Otherwise, if the protocol calls sofree(),
  411          * the socket will be released due to a zero refcount.
  412          */
  413         SOCK_LOCK(so);                  /* soref() and so_state update */
  414         soref(so);                      /* file descriptor reference */
  415 
  416         TAILQ_REMOVE(&head->so_comp, so, so_list);
  417         head->so_qlen--;
  418         if (flags & ACCEPT4_INHERIT)
  419                 so->so_state |= (head->so_state & SS_NBIO);
  420         else
  421                 so->so_state |= (flags & SOCK_NONBLOCK) ? SS_NBIO : 0;
  422         so->so_qstate &= ~SQ_COMP;
  423         so->so_head = NULL;
  424 
  425         SOCK_UNLOCK(so);
  426         ACCEPT_UNLOCK();
  427 
  428         /* An extra reference on `nfp' has been held for us by falloc(). */
  429         td->td_retval[0] = fd;
  430 
  431         /* connection has been removed from the listen queue */
  432         KNOTE_UNLOCKED(&head->so_rcv.sb_sel.si_note, 0);
  433 
  434         if (flags & ACCEPT4_INHERIT) {
  435                 pgid = fgetown(&head->so_sigio);
  436                 if (pgid != 0)
  437                         fsetown(pgid, &so->so_sigio);
  438         } else {
  439                 fflag &= ~(FNONBLOCK | FASYNC);
  440                 if (flags & SOCK_NONBLOCK)
  441                         fflag |= FNONBLOCK;
  442         }
  443 
  444         finit(nfp, fflag, DTYPE_SOCKET, so, &socketops);
  445         /* Sync socket nonblocking/async state with file flags */
  446         tmp = fflag & FNONBLOCK;
  447         (void) fo_ioctl(nfp, FIONBIO, &tmp, td->td_ucred, td);
  448         tmp = fflag & FASYNC;
  449         (void) fo_ioctl(nfp, FIOASYNC, &tmp, td->td_ucred, td);
  450         sa = NULL;
  451         error = soaccept(so, &sa);
  452         if (error != 0)
  453                 goto noconnection;
  454         if (sa == NULL) {
  455                 if (name)
  456                         *namelen = 0;
  457                 goto done;
  458         }
  459         AUDIT_ARG_SOCKADDR(td, AT_FDCWD, sa);
  460         if (name) {
  461                 /* check sa_len before it is destroyed */
  462                 if (*namelen > sa->sa_len)
  463                         *namelen = sa->sa_len;
  464 #ifdef KTRACE
  465                 if (KTRPOINT(td, KTR_STRUCT))
  466                         ktrsockaddr(sa);
  467 #endif
  468                 *name = sa;
  469                 sa = NULL;
  470         }
  471 noconnection:
  472         free(sa, M_SONAME);
  473 
  474         /*
  475          * close the new descriptor, assuming someone hasn't ripped it
  476          * out from under us.
  477          */
  478         if (error != 0)
  479                 fdclose(td, nfp, fd);
  480 
  481         /*
  482          * Release explicitly held references before returning.  We return
  483          * a reference on nfp to the caller on success if they request it.
  484          */
  485 done:
  486         if (nfp == NULL)
  487                 filecaps_free(&fcaps);
  488         if (fp != NULL) {
  489                 if (error == 0) {
  490                         *fp = nfp;
  491                         nfp = NULL;
  492                 } else
  493                         *fp = NULL;
  494         }
  495         if (nfp != NULL)
  496                 fdrop(nfp, td);
  497         fdrop(headfp, td);
  498         return (error);
  499 }
  500 
  501 int
  502 sys_accept(td, uap)
  503         struct thread *td;
  504         struct accept_args *uap;
  505 {
  506 
  507         return (accept1(td, uap->s, uap->name, uap->anamelen, ACCEPT4_INHERIT));
  508 }
  509 
  510 int
  511 sys_accept4(td, uap)
  512         struct thread *td;
  513         struct accept4_args *uap;
  514 {
  515 
  516         if (uap->flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
  517                 return (EINVAL);
  518 
  519         return (accept1(td, uap->s, uap->name, uap->anamelen, uap->flags));
  520 }
  521 
  522 #ifdef COMPAT_OLDSOCK
  523 int
  524 oaccept(td, uap)
  525         struct thread *td;
  526         struct accept_args *uap;
  527 {
  528 
  529         return (accept1(td, uap->s, uap->name, uap->anamelen,
  530             ACCEPT4_INHERIT | ACCEPT4_COMPAT));
  531 }
  532 #endif /* COMPAT_OLDSOCK */
  533 
  534 /* ARGSUSED */
  535 int
  536 sys_connect(td, uap)
  537         struct thread *td;
  538         struct connect_args /* {
  539                 int     s;
  540                 caddr_t name;
  541                 int     namelen;
  542         } */ *uap;
  543 {
  544         struct sockaddr *sa;
  545         int error;
  546 
  547         error = getsockaddr(&sa, uap->name, uap->namelen);
  548         if (error == 0) {
  549                 error = kern_connectat(td, AT_FDCWD, uap->s, sa);
  550                 free(sa, M_SONAME);
  551         }
  552         return (error);
  553 }
  554 
  555 int
  556 kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
  557 {
  558         struct socket *so;
  559         struct file *fp;
  560         cap_rights_t rights;
  561         int error, interrupted = 0;
  562 
  563         AUDIT_ARG_FD(fd);
  564         AUDIT_ARG_SOCKADDR(td, dirfd, sa);
  565         error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_CONNECT),
  566             &fp, NULL, NULL);
  567         if (error != 0)
  568                 return (error);
  569         so = fp->f_data;
  570         if (so->so_state & SS_ISCONNECTING) {
  571                 error = EALREADY;
  572                 goto done1;
  573         }
  574 #ifdef KTRACE
  575         if (KTRPOINT(td, KTR_STRUCT))
  576                 ktrsockaddr(sa);
  577 #endif
  578 #ifdef MAC
  579         error = mac_socket_check_connect(td->td_ucred, so, sa);
  580         if (error != 0)
  581                 goto bad;
  582 #endif
  583         if (dirfd == AT_FDCWD)
  584                 error = soconnect(so, sa, td);
  585         else
  586                 error = soconnectat(dirfd, so, sa, td);
  587         if (error != 0)
  588                 goto bad;
  589         if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
  590                 error = EINPROGRESS;
  591                 goto done1;
  592         }
  593         SOCK_LOCK(so);
  594         while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
  595                 error = msleep(&so->so_timeo, SOCK_MTX(so), PSOCK | PCATCH,
  596                     "connec", 0);
  597                 if (error != 0) {
  598                         if (error == EINTR || error == ERESTART)
  599                                 interrupted = 1;
  600                         break;
  601                 }
  602         }
  603         if (error == 0) {
  604                 error = so->so_error;
  605                 so->so_error = 0;
  606         }
  607         SOCK_UNLOCK(so);
  608 bad:
  609         if (!interrupted)
  610                 so->so_state &= ~SS_ISCONNECTING;
  611         if (error == ERESTART)
  612                 error = EINTR;
  613 done1:
  614         fdrop(fp, td);
  615         return (error);
  616 }
  617 
  618 /* ARGSUSED */
  619 int
  620 sys_connectat(td, uap)
  621         struct thread *td;
  622         struct connectat_args /* {
  623                 int     fd;
  624                 int     s;
  625                 caddr_t name;
  626                 int     namelen;
  627         } */ *uap;
  628 {
  629         struct sockaddr *sa;
  630         int error;
  631 
  632         error = getsockaddr(&sa, uap->name, uap->namelen);
  633         if (error == 0) {
  634                 error = kern_connectat(td, uap->fd, uap->s, sa);
  635                 free(sa, M_SONAME);
  636         }
  637         return (error);
  638 }
  639 
  640 int
  641 kern_socketpair(struct thread *td, int domain, int type, int protocol,
  642     int *rsv)
  643 {
  644         struct file *fp1, *fp2;
  645         struct socket *so1, *so2;
  646         int fd, error, oflag, fflag;
  647 
  648         AUDIT_ARG_SOCKET(domain, type, protocol);
  649 
  650         oflag = 0;
  651         fflag = 0;
  652         if ((type & SOCK_CLOEXEC) != 0) {
  653                 type &= ~SOCK_CLOEXEC;
  654                 oflag |= O_CLOEXEC;
  655         }
  656         if ((type & SOCK_NONBLOCK) != 0) {
  657                 type &= ~SOCK_NONBLOCK;
  658                 fflag |= FNONBLOCK;
  659         }
  660 #ifdef MAC
  661         /* We might want to have a separate check for socket pairs. */
  662         error = mac_socket_check_create(td->td_ucred, domain, type,
  663             protocol);
  664         if (error != 0)
  665                 return (error);
  666 #endif
  667         error = socreate(domain, &so1, type, protocol, td->td_ucred, td);
  668         if (error != 0)
  669                 return (error);
  670         error = socreate(domain, &so2, type, protocol, td->td_ucred, td);
  671         if (error != 0)
  672                 goto free1;
  673         /* On success extra reference to `fp1' and 'fp2' is set by falloc. */
  674         error = falloc(td, &fp1, &fd, oflag);
  675         if (error != 0)
  676                 goto free2;
  677         rsv[0] = fd;
  678         fp1->f_data = so1;      /* so1 already has ref count */
  679         error = falloc(td, &fp2, &fd, oflag);
  680         if (error != 0)
  681                 goto free3;
  682         fp2->f_data = so2;      /* so2 already has ref count */
  683         rsv[1] = fd;
  684         error = soconnect2(so1, so2);
  685         if (error != 0)
  686                 goto free4;
  687         if (type == SOCK_DGRAM) {
  688                 /*
  689                  * Datagram socket connection is asymmetric.
  690                  */
  691                  error = soconnect2(so2, so1);
  692                  if (error != 0)
  693                         goto free4;
  694         }
  695         finit(fp1, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp1->f_data,
  696             &socketops);
  697         finit(fp2, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp2->f_data,
  698             &socketops);
  699         if ((fflag & FNONBLOCK) != 0) {
  700                 (void) fo_ioctl(fp1, FIONBIO, &fflag, td->td_ucred, td);
  701                 (void) fo_ioctl(fp2, FIONBIO, &fflag, td->td_ucred, td);
  702         }
  703         fdrop(fp1, td);
  704         fdrop(fp2, td);
  705         return (0);
  706 free4:
  707         fdclose(td, fp2, rsv[1]);
  708         fdrop(fp2, td);
  709 free3:
  710         fdclose(td, fp1, rsv[0]);
  711         fdrop(fp1, td);
  712 free2:
  713         if (so2 != NULL)
  714                 (void)soclose(so2);
  715 free1:
  716         if (so1 != NULL)
  717                 (void)soclose(so1);
  718         return (error);
  719 }
  720 
  721 int
  722 sys_socketpair(struct thread *td, struct socketpair_args *uap)
  723 {
  724         int error, sv[2];
  725 
  726         error = kern_socketpair(td, uap->domain, uap->type,
  727             uap->protocol, sv);
  728         if (error != 0)
  729                 return (error);
  730         error = copyout(sv, uap->rsv, 2 * sizeof(int));
  731         if (error != 0) {
  732                 (void)kern_close(td, sv[0]);
  733                 (void)kern_close(td, sv[1]);
  734         }
  735         return (error);
  736 }
  737 
  738 static int
  739 sendit(td, s, mp, flags)
  740         struct thread *td;
  741         int s;
  742         struct msghdr *mp;
  743         int flags;
  744 {
  745         struct mbuf *control;
  746         struct sockaddr *to;
  747         int error;
  748 
  749 #ifdef CAPABILITY_MODE
  750         if (IN_CAPABILITY_MODE(td) && (mp->msg_name != NULL))
  751                 return (ECAPMODE);
  752 #endif
  753 
  754         if (mp->msg_name != NULL) {
  755                 error = getsockaddr(&to, mp->msg_name, mp->msg_namelen);
  756                 if (error != 0) {
  757                         to = NULL;
  758                         goto bad;
  759                 }
  760                 mp->msg_name = to;
  761         } else {
  762                 to = NULL;
  763         }
  764 
  765         if (mp->msg_control) {
  766                 if (mp->msg_controllen < sizeof(struct cmsghdr)
  767 #ifdef COMPAT_OLDSOCK
  768                     && mp->msg_flags != MSG_COMPAT
  769 #endif
  770                 ) {
  771                         error = EINVAL;
  772                         goto bad;
  773                 }
  774                 error = sockargs(&control, mp->msg_control,
  775                     mp->msg_controllen, MT_CONTROL);
  776                 if (error != 0)
  777                         goto bad;
  778 #ifdef COMPAT_OLDSOCK
  779                 if (mp->msg_flags == MSG_COMPAT) {
  780                         struct cmsghdr *cm;
  781 
  782                         M_PREPEND(control, sizeof(*cm), M_WAITOK);
  783                         cm = mtod(control, struct cmsghdr *);
  784                         cm->cmsg_len = control->m_len;
  785                         cm->cmsg_level = SOL_SOCKET;
  786                         cm->cmsg_type = SCM_RIGHTS;
  787                 }
  788 #endif
  789         } else {
  790                 control = NULL;
  791         }
  792 
  793         error = kern_sendit(td, s, mp, flags, control, UIO_USERSPACE);
  794 
  795 bad:
  796         free(to, M_SONAME);
  797         return (error);
  798 }
  799 
  800 int
  801 kern_sendit(td, s, mp, flags, control, segflg)
  802         struct thread *td;
  803         int s;
  804         struct msghdr *mp;
  805         int flags;
  806         struct mbuf *control;
  807         enum uio_seg segflg;
  808 {
  809         struct file *fp;
  810         struct uio auio;
  811         struct iovec *iov;
  812         struct socket *so;
  813         cap_rights_t rights;
  814 #ifdef KTRACE
  815         struct uio *ktruio = NULL;
  816 #endif
  817         ssize_t len;
  818         int i, error;
  819 
  820         AUDIT_ARG_FD(s);
  821         cap_rights_init(&rights, CAP_SEND);
  822         if (mp->msg_name != NULL) {
  823                 AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name);
  824                 cap_rights_set(&rights, CAP_CONNECT);
  825         }
  826         error = getsock_cap(td, s, &rights, &fp, NULL, NULL);
  827         if (error != 0) {
  828                 m_freem(control);
  829                 return (error);
  830         }
  831         so = (struct socket *)fp->f_data;
  832 
  833 #ifdef KTRACE
  834         if (mp->msg_name != NULL && KTRPOINT(td, KTR_STRUCT))
  835                 ktrsockaddr(mp->msg_name);
  836 #endif
  837 #ifdef MAC
  838         if (mp->msg_name != NULL) {
  839                 error = mac_socket_check_connect(td->td_ucred, so,
  840                     mp->msg_name);
  841                 if (error != 0) {
  842                         m_freem(control);
  843                         goto bad;
  844                 }
  845         }
  846         error = mac_socket_check_send(td->td_ucred, so);
  847         if (error != 0) {
  848                 m_freem(control);
  849                 goto bad;
  850         }
  851 #endif
  852 
  853         auio.uio_iov = mp->msg_iov;
  854         auio.uio_iovcnt = mp->msg_iovlen;
  855         auio.uio_segflg = segflg;
  856         auio.uio_rw = UIO_WRITE;
  857         auio.uio_td = td;
  858         auio.uio_offset = 0;                    /* XXX */
  859         auio.uio_resid = 0;
  860         iov = mp->msg_iov;
  861         for (i = 0; i < mp->msg_iovlen; i++, iov++) {
  862                 if ((auio.uio_resid += iov->iov_len) < 0) {
  863                         error = EINVAL;
  864                         m_freem(control);
  865                         goto bad;
  866                 }
  867         }
  868 #ifdef KTRACE
  869         if (KTRPOINT(td, KTR_GENIO))
  870                 ktruio = cloneuio(&auio);
  871 #endif
  872         len = auio.uio_resid;
  873         error = sosend(so, mp->msg_name, &auio, 0, control, flags, td);
  874         if (error != 0) {
  875                 if (auio.uio_resid != len && (error == ERESTART ||
  876                     error == EINTR || error == EWOULDBLOCK))
  877                         error = 0;
  878                 /* Generation of SIGPIPE can be controlled per socket */
  879                 if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
  880                     !(flags & MSG_NOSIGNAL)) {
  881                         PROC_LOCK(td->td_proc);
  882                         tdsignal(td, SIGPIPE);
  883                         PROC_UNLOCK(td->td_proc);
  884                 }
  885         }
  886         if (error == 0)
  887                 td->td_retval[0] = len - auio.uio_resid;
  888 #ifdef KTRACE
  889         if (ktruio != NULL) {
  890                 ktruio->uio_resid = td->td_retval[0];
  891                 ktrgenio(s, UIO_WRITE, ktruio, error);
  892         }
  893 #endif
  894 bad:
  895         fdrop(fp, td);
  896         return (error);
  897 }
  898 
  899 int
  900 sys_sendto(td, uap)
  901         struct thread *td;
  902         struct sendto_args /* {
  903                 int     s;
  904                 caddr_t buf;
  905                 size_t  len;
  906                 int     flags;
  907                 caddr_t to;
  908                 int     tolen;
  909         } */ *uap;
  910 {
  911         struct msghdr msg;
  912         struct iovec aiov;
  913 
  914         msg.msg_name = uap->to;
  915         msg.msg_namelen = uap->tolen;
  916         msg.msg_iov = &aiov;
  917         msg.msg_iovlen = 1;
  918         msg.msg_control = 0;
  919 #ifdef COMPAT_OLDSOCK
  920         msg.msg_flags = 0;
  921 #endif
  922         aiov.iov_base = uap->buf;
  923         aiov.iov_len = uap->len;
  924         return (sendit(td, uap->s, &msg, uap->flags));
  925 }
  926 
  927 #ifdef COMPAT_OLDSOCK
  928 int
  929 osend(td, uap)
  930         struct thread *td;
  931         struct osend_args /* {
  932                 int     s;
  933                 caddr_t buf;
  934                 int     len;
  935                 int     flags;
  936         } */ *uap;
  937 {
  938         struct msghdr msg;
  939         struct iovec aiov;
  940 
  941         msg.msg_name = 0;
  942         msg.msg_namelen = 0;
  943         msg.msg_iov = &aiov;
  944         msg.msg_iovlen = 1;
  945         aiov.iov_base = uap->buf;
  946         aiov.iov_len = uap->len;
  947         msg.msg_control = 0;
  948         msg.msg_flags = 0;
  949         return (sendit(td, uap->s, &msg, uap->flags));
  950 }
  951 
  952 int
  953 osendmsg(td, uap)
  954         struct thread *td;
  955         struct osendmsg_args /* {
  956                 int     s;
  957                 caddr_t msg;
  958                 int     flags;
  959         } */ *uap;
  960 {
  961         struct msghdr msg;
  962         struct iovec *iov;
  963         int error;
  964 
  965         error = copyin(uap->msg, &msg, sizeof (struct omsghdr));
  966         if (error != 0)
  967                 return (error);
  968         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
  969         if (error != 0)
  970                 return (error);
  971         msg.msg_iov = iov;
  972         msg.msg_flags = MSG_COMPAT;
  973         error = sendit(td, uap->s, &msg, uap->flags);
  974         free(iov, M_IOV);
  975         return (error);
  976 }
  977 #endif
  978 
  979 int
  980 sys_sendmsg(td, uap)
  981         struct thread *td;
  982         struct sendmsg_args /* {
  983                 int     s;
  984                 caddr_t msg;
  985                 int     flags;
  986         } */ *uap;
  987 {
  988         struct msghdr msg;
  989         struct iovec *iov;
  990         int error;
  991 
  992         error = copyin(uap->msg, &msg, sizeof (msg));
  993         if (error != 0)
  994                 return (error);
  995         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
  996         if (error != 0)
  997                 return (error);
  998         msg.msg_iov = iov;
  999 #ifdef COMPAT_OLDSOCK
 1000         msg.msg_flags = 0;
 1001 #endif
 1002         error = sendit(td, uap->s, &msg, uap->flags);
 1003         free(iov, M_IOV);
 1004         return (error);
 1005 }
 1006 
 1007 int
 1008 kern_recvit(td, s, mp, fromseg, controlp)
 1009         struct thread *td;
 1010         int s;
 1011         struct msghdr *mp;
 1012         enum uio_seg fromseg;
 1013         struct mbuf **controlp;
 1014 {
 1015         struct uio auio;
 1016         struct iovec *iov;
 1017         struct mbuf *m, *control = NULL;
 1018         caddr_t ctlbuf;
 1019         struct file *fp;
 1020         struct socket *so;
 1021         struct sockaddr *fromsa = NULL;
 1022         cap_rights_t rights;
 1023 #ifdef KTRACE
 1024         struct uio *ktruio = NULL;
 1025 #endif
 1026         ssize_t len;
 1027         int error, i;
 1028 
 1029         if (controlp != NULL)
 1030                 *controlp = NULL;
 1031 
 1032         AUDIT_ARG_FD(s);
 1033         error = getsock_cap(td, s, cap_rights_init(&rights, CAP_RECV),
 1034             &fp, NULL, NULL);
 1035         if (error != 0)
 1036                 return (error);
 1037         so = fp->f_data;
 1038 
 1039 #ifdef MAC
 1040         error = mac_socket_check_receive(td->td_ucred, so);
 1041         if (error != 0) {
 1042                 fdrop(fp, td);
 1043                 return (error);
 1044         }
 1045 #endif
 1046 
 1047         auio.uio_iov = mp->msg_iov;
 1048         auio.uio_iovcnt = mp->msg_iovlen;
 1049         auio.uio_segflg = UIO_USERSPACE;
 1050         auio.uio_rw = UIO_READ;
 1051         auio.uio_td = td;
 1052         auio.uio_offset = 0;                    /* XXX */
 1053         auio.uio_resid = 0;
 1054         iov = mp->msg_iov;
 1055         for (i = 0; i < mp->msg_iovlen; i++, iov++) {
 1056                 if ((auio.uio_resid += iov->iov_len) < 0) {
 1057                         fdrop(fp, td);
 1058                         return (EINVAL);
 1059                 }
 1060         }
 1061 #ifdef KTRACE
 1062         if (KTRPOINT(td, KTR_GENIO))
 1063                 ktruio = cloneuio(&auio);
 1064 #endif
 1065         len = auio.uio_resid;
 1066         error = soreceive(so, &fromsa, &auio, NULL,
 1067             (mp->msg_control || controlp) ? &control : NULL,
 1068             &mp->msg_flags);
 1069         if (error != 0) {
 1070                 if (auio.uio_resid != len && (error == ERESTART ||
 1071                     error == EINTR || error == EWOULDBLOCK))
 1072                         error = 0;
 1073         }
 1074         if (fromsa != NULL)
 1075                 AUDIT_ARG_SOCKADDR(td, AT_FDCWD, fromsa);
 1076 #ifdef KTRACE
 1077         if (ktruio != NULL) {
 1078                 ktruio->uio_resid = len - auio.uio_resid;
 1079                 ktrgenio(s, UIO_READ, ktruio, error);
 1080         }
 1081 #endif
 1082         if (error != 0)
 1083                 goto out;
 1084         td->td_retval[0] = len - auio.uio_resid;
 1085         if (mp->msg_name) {
 1086                 len = mp->msg_namelen;
 1087                 if (len <= 0 || fromsa == NULL)
 1088                         len = 0;
 1089                 else {
 1090                         /* save sa_len before it is destroyed by MSG_COMPAT */
 1091                         len = MIN(len, fromsa->sa_len);
 1092 #ifdef COMPAT_OLDSOCK
 1093                         if (mp->msg_flags & MSG_COMPAT)
 1094                                 ((struct osockaddr *)fromsa)->sa_family =
 1095                                     fromsa->sa_family;
 1096 #endif
 1097                         if (fromseg == UIO_USERSPACE) {
 1098                                 error = copyout(fromsa, mp->msg_name,
 1099                                     (unsigned)len);
 1100                                 if (error != 0)
 1101                                         goto out;
 1102                         } else
 1103                                 bcopy(fromsa, mp->msg_name, len);
 1104                 }
 1105                 mp->msg_namelen = len;
 1106         }
 1107         if (mp->msg_control && controlp == NULL) {
 1108 #ifdef COMPAT_OLDSOCK
 1109                 /*
 1110                  * We assume that old recvmsg calls won't receive access
 1111                  * rights and other control info, esp. as control info
 1112                  * is always optional and those options didn't exist in 4.3.
 1113                  * If we receive rights, trim the cmsghdr; anything else
 1114                  * is tossed.
 1115                  */
 1116                 if (control && mp->msg_flags & MSG_COMPAT) {
 1117                         if (mtod(control, struct cmsghdr *)->cmsg_level !=
 1118                             SOL_SOCKET ||
 1119                             mtod(control, struct cmsghdr *)->cmsg_type !=
 1120                             SCM_RIGHTS) {
 1121                                 mp->msg_controllen = 0;
 1122                                 goto out;
 1123                         }
 1124                         control->m_len -= sizeof (struct cmsghdr);
 1125                         control->m_data += sizeof (struct cmsghdr);
 1126                 }
 1127 #endif
 1128                 len = mp->msg_controllen;
 1129                 m = control;
 1130                 mp->msg_controllen = 0;
 1131                 ctlbuf = mp->msg_control;
 1132 
 1133                 while (m && len > 0) {
 1134                         unsigned int tocopy;
 1135 
 1136                         if (len >= m->m_len)
 1137                                 tocopy = m->m_len;
 1138                         else {
 1139                                 mp->msg_flags |= MSG_CTRUNC;
 1140                                 tocopy = len;
 1141                         }
 1142 
 1143                         if ((error = copyout(mtod(m, caddr_t),
 1144                                         ctlbuf, tocopy)) != 0)
 1145                                 goto out;
 1146 
 1147                         ctlbuf += tocopy;
 1148                         len -= tocopy;
 1149                         m = m->m_next;
 1150                 }
 1151                 mp->msg_controllen = ctlbuf - (caddr_t)mp->msg_control;
 1152         }
 1153 out:
 1154         fdrop(fp, td);
 1155 #ifdef KTRACE
 1156         if (fromsa && KTRPOINT(td, KTR_STRUCT))
 1157                 ktrsockaddr(fromsa);
 1158 #endif
 1159         free(fromsa, M_SONAME);
 1160 
 1161         if (error == 0 && controlp != NULL)
 1162                 *controlp = control;
 1163         else  if (control)
 1164                 m_freem(control);
 1165 
 1166         return (error);
 1167 }
 1168 
 1169 static int
 1170 recvit(td, s, mp, namelenp)
 1171         struct thread *td;
 1172         int s;
 1173         struct msghdr *mp;
 1174         void *namelenp;
 1175 {
 1176         int error;
 1177 
 1178         error = kern_recvit(td, s, mp, UIO_USERSPACE, NULL);
 1179         if (error != 0)
 1180                 return (error);
 1181         if (namelenp != NULL) {
 1182                 error = copyout(&mp->msg_namelen, namelenp, sizeof (socklen_t));
 1183 #ifdef COMPAT_OLDSOCK
 1184                 if (mp->msg_flags & MSG_COMPAT)
 1185                         error = 0;      /* old recvfrom didn't check */
 1186 #endif
 1187         }
 1188         return (error);
 1189 }
 1190 
 1191 int
 1192 sys_recvfrom(td, uap)
 1193         struct thread *td;
 1194         struct recvfrom_args /* {
 1195                 int     s;
 1196                 caddr_t buf;
 1197                 size_t  len;
 1198                 int     flags;
 1199                 struct sockaddr * __restrict    from;
 1200                 socklen_t * __restrict fromlenaddr;
 1201         } */ *uap;
 1202 {
 1203         struct msghdr msg;
 1204         struct iovec aiov;
 1205         int error;
 1206 
 1207         if (uap->fromlenaddr) {
 1208                 error = copyin(uap->fromlenaddr,
 1209                     &msg.msg_namelen, sizeof (msg.msg_namelen));
 1210                 if (error != 0)
 1211                         goto done2;
 1212         } else {
 1213                 msg.msg_namelen = 0;
 1214         }
 1215         msg.msg_name = uap->from;
 1216         msg.msg_iov = &aiov;
 1217         msg.msg_iovlen = 1;
 1218         aiov.iov_base = uap->buf;
 1219         aiov.iov_len = uap->len;
 1220         msg.msg_control = 0;
 1221         msg.msg_flags = uap->flags;
 1222         error = recvit(td, uap->s, &msg, uap->fromlenaddr);
 1223 done2:
 1224         return (error);
 1225 }
 1226 
 1227 #ifdef COMPAT_OLDSOCK
 1228 int
 1229 orecvfrom(td, uap)
 1230         struct thread *td;
 1231         struct recvfrom_args *uap;
 1232 {
 1233 
 1234         uap->flags |= MSG_COMPAT;
 1235         return (sys_recvfrom(td, uap));
 1236 }
 1237 #endif
 1238 
 1239 #ifdef COMPAT_OLDSOCK
 1240 int
 1241 orecv(td, uap)
 1242         struct thread *td;
 1243         struct orecv_args /* {
 1244                 int     s;
 1245                 caddr_t buf;
 1246                 int     len;
 1247                 int     flags;
 1248         } */ *uap;
 1249 {
 1250         struct msghdr msg;
 1251         struct iovec aiov;
 1252 
 1253         msg.msg_name = 0;
 1254         msg.msg_namelen = 0;
 1255         msg.msg_iov = &aiov;
 1256         msg.msg_iovlen = 1;
 1257         aiov.iov_base = uap->buf;
 1258         aiov.iov_len = uap->len;
 1259         msg.msg_control = 0;
 1260         msg.msg_flags = uap->flags;
 1261         return (recvit(td, uap->s, &msg, NULL));
 1262 }
 1263 
 1264 /*
 1265  * Old recvmsg.  This code takes advantage of the fact that the old msghdr
 1266  * overlays the new one, missing only the flags, and with the (old) access
 1267  * rights where the control fields are now.
 1268  */
 1269 int
 1270 orecvmsg(td, uap)
 1271         struct thread *td;
 1272         struct orecvmsg_args /* {
 1273                 int     s;
 1274                 struct  omsghdr *msg;
 1275                 int     flags;
 1276         } */ *uap;
 1277 {
 1278         struct msghdr msg;
 1279         struct iovec *iov;
 1280         int error;
 1281 
 1282         error = copyin(uap->msg, &msg, sizeof (struct omsghdr));
 1283         if (error != 0)
 1284                 return (error);
 1285         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
 1286         if (error != 0)
 1287                 return (error);
 1288         msg.msg_flags = uap->flags | MSG_COMPAT;
 1289         msg.msg_iov = iov;
 1290         error = recvit(td, uap->s, &msg, &uap->msg->msg_namelen);
 1291         if (msg.msg_controllen && error == 0)
 1292                 error = copyout(&msg.msg_controllen,
 1293                     &uap->msg->msg_accrightslen, sizeof (int));
 1294         free(iov, M_IOV);
 1295         return (error);
 1296 }
 1297 #endif
 1298 
 1299 int
 1300 sys_recvmsg(td, uap)
 1301         struct thread *td;
 1302         struct recvmsg_args /* {
 1303                 int     s;
 1304                 struct  msghdr *msg;
 1305                 int     flags;
 1306         } */ *uap;
 1307 {
 1308         struct msghdr msg;
 1309         struct iovec *uiov, *iov;
 1310         int error;
 1311 
 1312         error = copyin(uap->msg, &msg, sizeof (msg));
 1313         if (error != 0)
 1314                 return (error);
 1315         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
 1316         if (error != 0)
 1317                 return (error);
 1318         msg.msg_flags = uap->flags;
 1319 #ifdef COMPAT_OLDSOCK
 1320         msg.msg_flags &= ~MSG_COMPAT;
 1321 #endif
 1322         uiov = msg.msg_iov;
 1323         msg.msg_iov = iov;
 1324         error = recvit(td, uap->s, &msg, NULL);
 1325         if (error == 0) {
 1326                 msg.msg_iov = uiov;
 1327                 error = copyout(&msg, uap->msg, sizeof(msg));
 1328         }
 1329         free(iov, M_IOV);
 1330         return (error);
 1331 }
 1332 
 1333 /* ARGSUSED */
 1334 int
 1335 sys_shutdown(td, uap)
 1336         struct thread *td;
 1337         struct shutdown_args /* {
 1338                 int     s;
 1339                 int     how;
 1340         } */ *uap;
 1341 {
 1342 
 1343         return (kern_shutdown(td, uap->s, uap->how));
 1344 }
 1345 
 1346 int
 1347 kern_shutdown(struct thread *td, int s, int how)
 1348 {
 1349         struct socket *so;
 1350         struct file *fp;
 1351         cap_rights_t rights;
 1352         int error;
 1353 
 1354         AUDIT_ARG_FD(s);
 1355         error = getsock_cap(td, s, cap_rights_init(&rights, CAP_SHUTDOWN),
 1356             &fp, NULL, NULL);
 1357         if (error == 0) {
 1358                 so = fp->f_data;
 1359                 error = soshutdown(so, how);
 1360                 /*
 1361                  * Previous versions did not return ENOTCONN, but 0 in
 1362                  * case the socket was not connected. Some important
 1363                  * programs like syslogd up to r279016, 2015-02-19,
 1364                  * still depend on this behavior.
 1365                  */
 1366                 if (error == ENOTCONN &&
 1367                     td->td_proc->p_osrel < P_OSREL_SHUTDOWN_ENOTCONN)
 1368                         error = 0;
 1369                 fdrop(fp, td);
 1370         }
 1371         return (error);
 1372 }
 1373 
 1374 /* ARGSUSED */
 1375 int
 1376 sys_setsockopt(td, uap)
 1377         struct thread *td;
 1378         struct setsockopt_args /* {
 1379                 int     s;
 1380                 int     level;
 1381                 int     name;
 1382                 caddr_t val;
 1383                 int     valsize;
 1384         } */ *uap;
 1385 {
 1386 
 1387         return (kern_setsockopt(td, uap->s, uap->level, uap->name,
 1388             uap->val, UIO_USERSPACE, uap->valsize));
 1389 }
 1390 
 1391 int
 1392 kern_setsockopt(td, s, level, name, val, valseg, valsize)
 1393         struct thread *td;
 1394         int s;
 1395         int level;
 1396         int name;
 1397         void *val;
 1398         enum uio_seg valseg;
 1399         socklen_t valsize;
 1400 {
 1401         struct socket *so;
 1402         struct file *fp;
 1403         struct sockopt sopt;
 1404         cap_rights_t rights;
 1405         int error;
 1406 
 1407         if (val == NULL && valsize != 0)
 1408                 return (EFAULT);
 1409         if ((int)valsize < 0)
 1410                 return (EINVAL);
 1411 
 1412         sopt.sopt_dir = SOPT_SET;
 1413         sopt.sopt_level = level;
 1414         sopt.sopt_name = name;
 1415         sopt.sopt_val = val;
 1416         sopt.sopt_valsize = valsize;
 1417         switch (valseg) {
 1418         case UIO_USERSPACE:
 1419                 sopt.sopt_td = td;
 1420                 break;
 1421         case UIO_SYSSPACE:
 1422                 sopt.sopt_td = NULL;
 1423                 break;
 1424         default:
 1425                 panic("kern_setsockopt called with bad valseg");
 1426         }
 1427 
 1428         AUDIT_ARG_FD(s);
 1429         error = getsock_cap(td, s, cap_rights_init(&rights, CAP_SETSOCKOPT),
 1430             &fp, NULL, NULL);
 1431         if (error == 0) {
 1432                 so = fp->f_data;
 1433                 error = sosetopt(so, &sopt);
 1434                 fdrop(fp, td);
 1435         }
 1436         return(error);
 1437 }
 1438 
 1439 /* ARGSUSED */
 1440 int
 1441 sys_getsockopt(td, uap)
 1442         struct thread *td;
 1443         struct getsockopt_args /* {
 1444                 int     s;
 1445                 int     level;
 1446                 int     name;
 1447                 void * __restrict       val;
 1448                 socklen_t * __restrict avalsize;
 1449         } */ *uap;
 1450 {
 1451         socklen_t valsize;
 1452         int error;
 1453 
 1454         if (uap->val) {
 1455                 error = copyin(uap->avalsize, &valsize, sizeof (valsize));
 1456                 if (error != 0)
 1457                         return (error);
 1458         }
 1459 
 1460         error = kern_getsockopt(td, uap->s, uap->level, uap->name,
 1461             uap->val, UIO_USERSPACE, &valsize);
 1462 
 1463         if (error == 0)
 1464                 error = copyout(&valsize, uap->avalsize, sizeof (valsize));
 1465         return (error);
 1466 }
 1467 
 1468 /*
 1469  * Kernel version of getsockopt.
 1470  * optval can be a userland or userspace. optlen is always a kernel pointer.
 1471  */
 1472 int
 1473 kern_getsockopt(td, s, level, name, val, valseg, valsize)
 1474         struct thread *td;
 1475         int s;
 1476         int level;
 1477         int name;
 1478         void *val;
 1479         enum uio_seg valseg;
 1480         socklen_t *valsize;
 1481 {
 1482         struct socket *so;
 1483         struct file *fp;
 1484         struct sockopt sopt;
 1485         cap_rights_t rights;
 1486         int error;
 1487 
 1488         if (val == NULL)
 1489                 *valsize = 0;
 1490         if ((int)*valsize < 0)
 1491                 return (EINVAL);
 1492 
 1493         sopt.sopt_dir = SOPT_GET;
 1494         sopt.sopt_level = level;
 1495         sopt.sopt_name = name;
 1496         sopt.sopt_val = val;
 1497         sopt.sopt_valsize = (size_t)*valsize; /* checked non-negative above */
 1498         switch (valseg) {
 1499         case UIO_USERSPACE:
 1500                 sopt.sopt_td = td;
 1501                 break;
 1502         case UIO_SYSSPACE:
 1503                 sopt.sopt_td = NULL;
 1504                 break;
 1505         default:
 1506                 panic("kern_getsockopt called with bad valseg");
 1507         }
 1508 
 1509         AUDIT_ARG_FD(s);
 1510         error = getsock_cap(td, s, cap_rights_init(&rights, CAP_GETSOCKOPT),
 1511             &fp, NULL, NULL);
 1512         if (error == 0) {
 1513                 so = fp->f_data;
 1514                 error = sogetopt(so, &sopt);
 1515                 *valsize = sopt.sopt_valsize;
 1516                 fdrop(fp, td);
 1517         }
 1518         return (error);
 1519 }
 1520 
 1521 /*
 1522  * getsockname1() - Get socket name.
 1523  */
 1524 /* ARGSUSED */
 1525 static int
 1526 getsockname1(td, uap, compat)
 1527         struct thread *td;
 1528         struct getsockname_args /* {
 1529                 int     fdes;
 1530                 struct sockaddr * __restrict asa;
 1531                 socklen_t * __restrict alen;
 1532         } */ *uap;
 1533         int compat;
 1534 {
 1535         struct sockaddr *sa;
 1536         socklen_t len;
 1537         int error;
 1538 
 1539         error = copyin(uap->alen, &len, sizeof(len));
 1540         if (error != 0)
 1541                 return (error);
 1542 
 1543         error = kern_getsockname(td, uap->fdes, &sa, &len);
 1544         if (error != 0)
 1545                 return (error);
 1546 
 1547         if (len != 0) {
 1548 #ifdef COMPAT_OLDSOCK
 1549                 if (compat)
 1550                         ((struct osockaddr *)sa)->sa_family = sa->sa_family;
 1551 #endif
 1552                 error = copyout(sa, uap->asa, (u_int)len);
 1553         }
 1554         free(sa, M_SONAME);
 1555         if (error == 0)
 1556                 error = copyout(&len, uap->alen, sizeof(len));
 1557         return (error);
 1558 }
 1559 
 1560 int
 1561 kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
 1562     socklen_t *alen)
 1563 {
 1564         struct socket *so;
 1565         struct file *fp;
 1566         cap_rights_t rights;
 1567         socklen_t len;
 1568         int error;
 1569 
 1570         AUDIT_ARG_FD(fd);
 1571         error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETSOCKNAME),
 1572             &fp, NULL, NULL);
 1573         if (error != 0)
 1574                 return (error);
 1575         so = fp->f_data;
 1576         *sa = NULL;
 1577         CURVNET_SET(so->so_vnet);
 1578         error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, sa);
 1579         CURVNET_RESTORE();
 1580         if (error != 0)
 1581                 goto bad;
 1582         if (*sa == NULL)
 1583                 len = 0;
 1584         else
 1585                 len = MIN(*alen, (*sa)->sa_len);
 1586         *alen = len;
 1587 #ifdef KTRACE
 1588         if (KTRPOINT(td, KTR_STRUCT))
 1589                 ktrsockaddr(*sa);
 1590 #endif
 1591 bad:
 1592         fdrop(fp, td);
 1593         if (error != 0 && *sa != NULL) {
 1594                 free(*sa, M_SONAME);
 1595                 *sa = NULL;
 1596         }
 1597         return (error);
 1598 }
 1599 
 1600 int
 1601 sys_getsockname(td, uap)
 1602         struct thread *td;
 1603         struct getsockname_args *uap;
 1604 {
 1605 
 1606         return (getsockname1(td, uap, 0));
 1607 }
 1608 
 1609 #ifdef COMPAT_OLDSOCK
 1610 int
 1611 ogetsockname(td, uap)
 1612         struct thread *td;
 1613         struct getsockname_args *uap;
 1614 {
 1615 
 1616         return (getsockname1(td, uap, 1));
 1617 }
 1618 #endif /* COMPAT_OLDSOCK */
 1619 
 1620 /*
 1621  * getpeername1() - Get name of peer for connected socket.
 1622  */
 1623 /* ARGSUSED */
 1624 static int
 1625 getpeername1(td, uap, compat)
 1626         struct thread *td;
 1627         struct getpeername_args /* {
 1628                 int     fdes;
 1629                 struct sockaddr * __restrict    asa;
 1630                 socklen_t * __restrict  alen;
 1631         } */ *uap;
 1632         int compat;
 1633 {
 1634         struct sockaddr *sa;
 1635         socklen_t len;
 1636         int error;
 1637 
 1638         error = copyin(uap->alen, &len, sizeof (len));
 1639         if (error != 0)
 1640                 return (error);
 1641 
 1642         error = kern_getpeername(td, uap->fdes, &sa, &len);
 1643         if (error != 0)
 1644                 return (error);
 1645 
 1646         if (len != 0) {
 1647 #ifdef COMPAT_OLDSOCK
 1648                 if (compat)
 1649                         ((struct osockaddr *)sa)->sa_family = sa->sa_family;
 1650 #endif
 1651                 error = copyout(sa, uap->asa, (u_int)len);
 1652         }
 1653         free(sa, M_SONAME);
 1654         if (error == 0)
 1655                 error = copyout(&len, uap->alen, sizeof(len));
 1656         return (error);
 1657 }
 1658 
 1659 int
 1660 kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
 1661     socklen_t *alen)
 1662 {
 1663         struct socket *so;
 1664         struct file *fp;
 1665         cap_rights_t rights;
 1666         socklen_t len;
 1667         int error;
 1668 
 1669         AUDIT_ARG_FD(fd);
 1670         error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETPEERNAME),
 1671             &fp, NULL, NULL);
 1672         if (error != 0)
 1673                 return (error);
 1674         so = fp->f_data;
 1675         if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) {
 1676                 error = ENOTCONN;
 1677                 goto done;
 1678         }
 1679         *sa = NULL;
 1680         CURVNET_SET(so->so_vnet);
 1681         error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, sa);
 1682         CURVNET_RESTORE();
 1683         if (error != 0)
 1684                 goto bad;
 1685         if (*sa == NULL)
 1686                 len = 0;
 1687         else
 1688                 len = MIN(*alen, (*sa)->sa_len);
 1689         *alen = len;
 1690 #ifdef KTRACE
 1691         if (KTRPOINT(td, KTR_STRUCT))
 1692                 ktrsockaddr(*sa);
 1693 #endif
 1694 bad:
 1695         if (error != 0 && *sa != NULL) {
 1696                 free(*sa, M_SONAME);
 1697                 *sa = NULL;
 1698         }
 1699 done:
 1700         fdrop(fp, td);
 1701         return (error);
 1702 }
 1703 
 1704 int
 1705 sys_getpeername(td, uap)
 1706         struct thread *td;
 1707         struct getpeername_args *uap;
 1708 {
 1709 
 1710         return (getpeername1(td, uap, 0));
 1711 }
 1712 
 1713 #ifdef COMPAT_OLDSOCK
 1714 int
 1715 ogetpeername(td, uap)
 1716         struct thread *td;
 1717         struct ogetpeername_args *uap;
 1718 {
 1719 
 1720         /* XXX uap should have type `getpeername_args *' to begin with. */
 1721         return (getpeername1(td, (struct getpeername_args *)uap, 1));
 1722 }
 1723 #endif /* COMPAT_OLDSOCK */
 1724 
 1725 static int
 1726 sockargs(struct mbuf **mp, char *buf, socklen_t buflen, int type)
 1727 {
 1728         struct sockaddr *sa;
 1729         struct mbuf *m;
 1730         int error;
 1731 
 1732         if (buflen > MLEN) {
 1733 #ifdef COMPAT_OLDSOCK
 1734                 if (type == MT_SONAME && buflen <= 112)
 1735                         buflen = MLEN;          /* unix domain compat. hack */
 1736                 else
 1737 #endif
 1738                         if (buflen > MCLBYTES)
 1739                                 return (EINVAL);
 1740         }
 1741         m = m_get2(buflen, M_WAITOK, type, 0);
 1742         m->m_len = buflen;
 1743         error = copyin(buf, mtod(m, void *), buflen);
 1744         if (error != 0)
 1745                 (void) m_free(m);
 1746         else {
 1747                 *mp = m;
 1748                 if (type == MT_SONAME) {
 1749                         sa = mtod(m, struct sockaddr *);
 1750 
 1751 #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
 1752                         if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
 1753                                 sa->sa_family = sa->sa_len;
 1754 #endif
 1755                         sa->sa_len = buflen;
 1756                 }
 1757         }
 1758         return (error);
 1759 }
 1760 
 1761 int
 1762 getsockaddr(namp, uaddr, len)
 1763         struct sockaddr **namp;
 1764         caddr_t uaddr;
 1765         size_t len;
 1766 {
 1767         struct sockaddr *sa;
 1768         int error;
 1769 
 1770         if (len > SOCK_MAXADDRLEN)
 1771                 return (ENAMETOOLONG);
 1772         if (len < offsetof(struct sockaddr, sa_data[0]))
 1773                 return (EINVAL);
 1774         sa = malloc(len, M_SONAME, M_WAITOK);
 1775         error = copyin(uaddr, sa, len);
 1776         if (error != 0) {
 1777                 free(sa, M_SONAME);
 1778         } else {
 1779 #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
 1780                 if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
 1781                         sa->sa_family = sa->sa_len;
 1782 #endif
 1783                 sa->sa_len = len;
 1784                 *namp = sa;
 1785         }
 1786         return (error);
 1787 }

Cache object: 190e57e40a9045f81eb497686c55f7c9


[ 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.