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

Cache object: 8d099c8e3b3e3a1ee9f7953a2da7d267


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