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(td, uap)
  461         struct thread *td;
  462         struct accept_args *uap;
  463 {
  464 
  465         return (accept1(td, uap->s, uap->name, uap->anamelen,
  466             ACCEPT4_INHERIT | ACCEPT4_COMPAT));
  467 }
  468 #endif /* COMPAT_OLDSOCK */
  469 
  470 int
  471 sys_connect(struct thread *td, struct connect_args *uap)
  472 {
  473         struct sockaddr *sa;
  474         int error;
  475 
  476         error = getsockaddr(&sa, uap->name, uap->namelen);
  477         if (error == 0) {
  478                 error = kern_connectat(td, AT_FDCWD, uap->s, sa);
  479                 free(sa, M_SONAME);
  480         }
  481         return (error);
  482 }
  483 
  484 int
  485 kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
  486 {
  487         struct socket *so;
  488         struct file *fp;
  489         int error, interrupted = 0;
  490 
  491 #ifdef CAPABILITY_MODE
  492         if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD))
  493                 return (ECAPMODE);
  494 #endif
  495 
  496         AUDIT_ARG_FD(fd);
  497         AUDIT_ARG_SOCKADDR(td, dirfd, sa);
  498         error = getsock_cap(td, fd, &cap_connect_rights,
  499             &fp, NULL, NULL);
  500         if (error != 0)
  501                 return (error);
  502         so = fp->f_data;
  503         if (so->so_state & SS_ISCONNECTING) {
  504                 error = EALREADY;
  505                 goto done1;
  506         }
  507 #ifdef KTRACE
  508         if (KTRPOINT(td, KTR_STRUCT))
  509                 ktrsockaddr(sa);
  510 #endif
  511 #ifdef MAC
  512         error = mac_socket_check_connect(td->td_ucred, so, sa);
  513         if (error != 0)
  514                 goto bad;
  515 #endif
  516         if (dirfd == AT_FDCWD)
  517                 error = soconnect(so, sa, td);
  518         else
  519                 error = soconnectat(dirfd, so, sa, td);
  520         if (error != 0)
  521                 goto bad;
  522         if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
  523                 error = EINPROGRESS;
  524                 goto done1;
  525         }
  526         SOCK_LOCK(so);
  527         while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
  528                 error = msleep(&so->so_timeo, &so->so_lock, PSOCK | PCATCH,
  529                     "connec", 0);
  530                 if (error != 0) {
  531                         if (error == EINTR || error == ERESTART)
  532                                 interrupted = 1;
  533                         break;
  534                 }
  535         }
  536         if (error == 0) {
  537                 error = so->so_error;
  538                 so->so_error = 0;
  539         }
  540         SOCK_UNLOCK(so);
  541 bad:
  542         if (!interrupted)
  543                 so->so_state &= ~SS_ISCONNECTING;
  544         if (error == ERESTART)
  545                 error = EINTR;
  546 done1:
  547         fdrop(fp, td);
  548         return (error);
  549 }
  550 
  551 int
  552 sys_connectat(struct thread *td, struct connectat_args *uap)
  553 {
  554         struct sockaddr *sa;
  555         int error;
  556 
  557         error = getsockaddr(&sa, uap->name, uap->namelen);
  558         if (error == 0) {
  559                 error = kern_connectat(td, uap->fd, uap->s, sa);
  560                 free(sa, M_SONAME);
  561         }
  562         return (error);
  563 }
  564 
  565 int
  566 kern_socketpair(struct thread *td, int domain, int type, int protocol,
  567     int *rsv)
  568 {
  569         struct file *fp1, *fp2;
  570         struct socket *so1, *so2;
  571         int fd, error, oflag, fflag;
  572 
  573         AUDIT_ARG_SOCKET(domain, type, protocol);
  574 
  575         oflag = 0;
  576         fflag = 0;
  577         if ((type & SOCK_CLOEXEC) != 0) {
  578                 type &= ~SOCK_CLOEXEC;
  579                 oflag |= O_CLOEXEC;
  580         }
  581         if ((type & SOCK_NONBLOCK) != 0) {
  582                 type &= ~SOCK_NONBLOCK;
  583                 fflag |= FNONBLOCK;
  584         }
  585 #ifdef MAC
  586         /* We might want to have a separate check for socket pairs. */
  587         error = mac_socket_check_create(td->td_ucred, domain, type,
  588             protocol);
  589         if (error != 0)
  590                 return (error);
  591 #endif
  592         error = socreate(domain, &so1, type, protocol, td->td_ucred, td);
  593         if (error != 0)
  594                 return (error);
  595         error = socreate(domain, &so2, type, protocol, td->td_ucred, td);
  596         if (error != 0)
  597                 goto free1;
  598         /* On success extra reference to `fp1' and 'fp2' is set by falloc. */
  599         error = falloc(td, &fp1, &fd, oflag);
  600         if (error != 0)
  601                 goto free2;
  602         rsv[0] = fd;
  603         fp1->f_data = so1;      /* so1 already has ref count */
  604         error = falloc(td, &fp2, &fd, oflag);
  605         if (error != 0)
  606                 goto free3;
  607         fp2->f_data = so2;      /* so2 already has ref count */
  608         rsv[1] = fd;
  609         error = soconnect2(so1, so2);
  610         if (error != 0)
  611                 goto free4;
  612         if (type == SOCK_DGRAM) {
  613                 /*
  614                  * Datagram socket connection is asymmetric.
  615                  */
  616                  error = soconnect2(so2, so1);
  617                  if (error != 0)
  618                         goto free4;
  619         } else if (so1->so_proto->pr_flags & PR_CONNREQUIRED) {
  620                 struct unpcb *unp, *unp2;
  621                 unp = sotounpcb(so1);
  622                 unp2 = sotounpcb(so2);
  623                 /* 
  624                  * No need to lock the unps, because the sockets are brand-new.
  625                  * No other threads can be using them yet
  626                  */
  627                 unp_copy_peercred(td, unp, unp2, unp);
  628         }
  629         finit(fp1, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp1->f_data,
  630             &socketops);
  631         finit(fp2, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp2->f_data,
  632             &socketops);
  633         if ((fflag & FNONBLOCK) != 0) {
  634                 (void) fo_ioctl(fp1, FIONBIO, &fflag, td->td_ucred, td);
  635                 (void) fo_ioctl(fp2, FIONBIO, &fflag, td->td_ucred, td);
  636         }
  637         fdrop(fp1, td);
  638         fdrop(fp2, td);
  639         return (0);
  640 free4:
  641         fdclose(td, fp2, rsv[1]);
  642         fdrop(fp2, td);
  643 free3:
  644         fdclose(td, fp1, rsv[0]);
  645         fdrop(fp1, td);
  646 free2:
  647         if (so2 != NULL)
  648                 (void)soclose(so2);
  649 free1:
  650         if (so1 != NULL)
  651                 (void)soclose(so1);
  652         return (error);
  653 }
  654 
  655 int
  656 sys_socketpair(struct thread *td, struct socketpair_args *uap)
  657 {
  658         int error, sv[2];
  659 
  660         error = kern_socketpair(td, uap->domain, uap->type,
  661             uap->protocol, sv);
  662         if (error != 0)
  663                 return (error);
  664         error = copyout(sv, uap->rsv, 2 * sizeof(int));
  665         if (error != 0) {
  666                 (void)kern_close(td, sv[0]);
  667                 (void)kern_close(td, sv[1]);
  668         }
  669         return (error);
  670 }
  671 
  672 static int
  673 sendit(struct thread *td, int s, struct msghdr *mp, int flags)
  674 {
  675         struct mbuf *control;
  676         struct sockaddr *to;
  677         int error;
  678 
  679 #ifdef CAPABILITY_MODE
  680         if (IN_CAPABILITY_MODE(td) && (mp->msg_name != NULL))
  681                 return (ECAPMODE);
  682 #endif
  683 
  684         if (mp->msg_name != NULL) {
  685                 error = getsockaddr(&to, mp->msg_name, mp->msg_namelen);
  686                 if (error != 0) {
  687                         to = NULL;
  688                         goto bad;
  689                 }
  690                 mp->msg_name = to;
  691         } else {
  692                 to = NULL;
  693         }
  694 
  695         if (mp->msg_control) {
  696                 if (mp->msg_controllen < sizeof(struct cmsghdr)
  697 #ifdef COMPAT_OLDSOCK
  698                     && (mp->msg_flags != MSG_COMPAT ||
  699                     !SV_PROC_FLAG(td->td_proc, SV_AOUT))
  700 #endif
  701                 ) {
  702                         error = EINVAL;
  703                         goto bad;
  704                 }
  705                 error = sockargs(&control, mp->msg_control,
  706                     mp->msg_controllen, MT_CONTROL);
  707                 if (error != 0)
  708                         goto bad;
  709 #ifdef COMPAT_OLDSOCK
  710                 if (mp->msg_flags == MSG_COMPAT &&
  711                     SV_PROC_FLAG(td->td_proc, SV_AOUT)) {
  712                         struct cmsghdr *cm;
  713 
  714                         M_PREPEND(control, sizeof(*cm), M_WAITOK);
  715                         cm = mtod(control, struct cmsghdr *);
  716                         cm->cmsg_len = control->m_len;
  717                         cm->cmsg_level = SOL_SOCKET;
  718                         cm->cmsg_type = SCM_RIGHTS;
  719                 }
  720 #endif
  721         } else {
  722                 control = NULL;
  723         }
  724 
  725         error = kern_sendit(td, s, mp, flags, control, UIO_USERSPACE);
  726 
  727 bad:
  728         free(to, M_SONAME);
  729         return (error);
  730 }
  731 
  732 int
  733 kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
  734     struct mbuf *control, enum uio_seg segflg)
  735 {
  736         struct file *fp;
  737         struct uio auio;
  738         struct iovec *iov;
  739         struct socket *so;
  740         cap_rights_t *rights;
  741 #ifdef KTRACE
  742         struct uio *ktruio = NULL;
  743 #endif
  744         ssize_t len;
  745         int i, error;
  746 
  747         AUDIT_ARG_FD(s);
  748         rights = &cap_send_rights;
  749         if (mp->msg_name != NULL) {
  750                 AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name);
  751                 rights = &cap_send_connect_rights;
  752         }
  753         error = getsock_cap(td, s, rights, &fp, NULL, NULL);
  754         if (error != 0) {
  755                 m_freem(control);
  756                 return (error);
  757         }
  758         so = (struct socket *)fp->f_data;
  759 
  760 #ifdef KTRACE
  761         if (mp->msg_name != NULL && KTRPOINT(td, KTR_STRUCT))
  762                 ktrsockaddr(mp->msg_name);
  763 #endif
  764 #ifdef MAC
  765         if (mp->msg_name != NULL) {
  766                 error = mac_socket_check_connect(td->td_ucred, so,
  767                     mp->msg_name);
  768                 if (error != 0) {
  769                         m_freem(control);
  770                         goto bad;
  771                 }
  772         }
  773         error = mac_socket_check_send(td->td_ucred, so);
  774         if (error != 0) {
  775                 m_freem(control);
  776                 goto bad;
  777         }
  778 #endif
  779 
  780         auio.uio_iov = mp->msg_iov;
  781         auio.uio_iovcnt = mp->msg_iovlen;
  782         auio.uio_segflg = segflg;
  783         auio.uio_rw = UIO_WRITE;
  784         auio.uio_td = td;
  785         auio.uio_offset = 0;                    /* XXX */
  786         auio.uio_resid = 0;
  787         iov = mp->msg_iov;
  788         for (i = 0; i < mp->msg_iovlen; i++, iov++) {
  789                 if ((auio.uio_resid += iov->iov_len) < 0) {
  790                         error = EINVAL;
  791                         m_freem(control);
  792                         goto bad;
  793                 }
  794         }
  795 #ifdef KTRACE
  796         if (KTRPOINT(td, KTR_GENIO))
  797                 ktruio = cloneuio(&auio);
  798 #endif
  799         len = auio.uio_resid;
  800         error = sosend(so, mp->msg_name, &auio, 0, control, flags, td);
  801         if (error != 0) {
  802                 if (auio.uio_resid != len && (error == ERESTART ||
  803                     error == EINTR || error == EWOULDBLOCK))
  804                         error = 0;
  805                 /* Generation of SIGPIPE can be controlled per socket */
  806                 if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
  807                     !(flags & MSG_NOSIGNAL)) {
  808                         PROC_LOCK(td->td_proc);
  809                         tdsignal(td, SIGPIPE);
  810                         PROC_UNLOCK(td->td_proc);
  811                 }
  812         }
  813         if (error == 0)
  814                 td->td_retval[0] = len - auio.uio_resid;
  815 #ifdef KTRACE
  816         if (ktruio != NULL) {
  817                 ktruio->uio_resid = td->td_retval[0];
  818                 ktrgenio(s, UIO_WRITE, ktruio, error);
  819         }
  820 #endif
  821 bad:
  822         fdrop(fp, td);
  823         return (error);
  824 }
  825 
  826 int
  827 sys_sendto(struct thread *td, struct sendto_args *uap)
  828 {
  829         struct msghdr msg;
  830         struct iovec aiov;
  831 
  832         msg.msg_name = uap->to;
  833         msg.msg_namelen = uap->tolen;
  834         msg.msg_iov = &aiov;
  835         msg.msg_iovlen = 1;
  836         msg.msg_control = 0;
  837 #ifdef COMPAT_OLDSOCK
  838         if (SV_PROC_FLAG(td->td_proc, SV_AOUT))
  839                 msg.msg_flags = 0;
  840 #endif
  841         aiov.iov_base = uap->buf;
  842         aiov.iov_len = uap->len;
  843         return (sendit(td, uap->s, &msg, uap->flags));
  844 }
  845 
  846 #ifdef COMPAT_OLDSOCK
  847 int
  848 osend(struct thread *td, struct osend_args *uap)
  849 {
  850         struct msghdr msg;
  851         struct iovec aiov;
  852 
  853         msg.msg_name = 0;
  854         msg.msg_namelen = 0;
  855         msg.msg_iov = &aiov;
  856         msg.msg_iovlen = 1;
  857         aiov.iov_base = uap->buf;
  858         aiov.iov_len = uap->len;
  859         msg.msg_control = 0;
  860         msg.msg_flags = 0;
  861         return (sendit(td, uap->s, &msg, uap->flags));
  862 }
  863 
  864 int
  865 osendmsg(struct thread *td, struct osendmsg_args *uap)
  866 {
  867         struct msghdr msg;
  868         struct iovec *iov;
  869         int error;
  870 
  871         error = copyin(uap->msg, &msg, sizeof (struct omsghdr));
  872         if (error != 0)
  873                 return (error);
  874         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
  875         if (error != 0)
  876                 return (error);
  877         msg.msg_iov = iov;
  878         msg.msg_flags = MSG_COMPAT;
  879         error = sendit(td, uap->s, &msg, uap->flags);
  880         free(iov, M_IOV);
  881         return (error);
  882 }
  883 #endif
  884 
  885 int
  886 sys_sendmsg(struct thread *td, struct sendmsg_args *uap)
  887 {
  888         struct msghdr msg;
  889         struct iovec *iov;
  890         int error;
  891 
  892         error = copyin(uap->msg, &msg, sizeof (msg));
  893         if (error != 0)
  894                 return (error);
  895         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
  896         if (error != 0)
  897                 return (error);
  898         msg.msg_iov = iov;
  899 #ifdef COMPAT_OLDSOCK
  900         if (SV_PROC_FLAG(td->td_proc, SV_AOUT))
  901                 msg.msg_flags = 0;
  902 #endif
  903         error = sendit(td, uap->s, &msg, uap->flags);
  904         free(iov, M_IOV);
  905         return (error);
  906 }
  907 
  908 int
  909 kern_recvit(struct thread *td, int s, struct msghdr *mp, enum uio_seg fromseg,
  910     struct mbuf **controlp)
  911 {
  912         struct uio auio;
  913         struct iovec *iov;
  914         struct mbuf *control, *m;
  915         caddr_t ctlbuf;
  916         struct file *fp;
  917         struct socket *so;
  918         struct sockaddr *fromsa = NULL;
  919 #ifdef KTRACE
  920         struct uio *ktruio = NULL;
  921 #endif
  922         ssize_t len;
  923         int error, i;
  924 
  925         if (controlp != NULL)
  926                 *controlp = NULL;
  927 
  928         AUDIT_ARG_FD(s);
  929         error = getsock_cap(td, s, &cap_recv_rights,
  930             &fp, NULL, NULL);
  931         if (error != 0)
  932                 return (error);
  933         so = fp->f_data;
  934 
  935 #ifdef MAC
  936         error = mac_socket_check_receive(td->td_ucred, so);
  937         if (error != 0) {
  938                 fdrop(fp, td);
  939                 return (error);
  940         }
  941 #endif
  942 
  943         auio.uio_iov = mp->msg_iov;
  944         auio.uio_iovcnt = mp->msg_iovlen;
  945         auio.uio_segflg = UIO_USERSPACE;
  946         auio.uio_rw = UIO_READ;
  947         auio.uio_td = td;
  948         auio.uio_offset = 0;                    /* XXX */
  949         auio.uio_resid = 0;
  950         iov = mp->msg_iov;
  951         for (i = 0; i < mp->msg_iovlen; i++, iov++) {
  952                 if ((auio.uio_resid += iov->iov_len) < 0) {
  953                         fdrop(fp, td);
  954                         return (EINVAL);
  955                 }
  956         }
  957 #ifdef KTRACE
  958         if (KTRPOINT(td, KTR_GENIO))
  959                 ktruio = cloneuio(&auio);
  960 #endif
  961         control = NULL;
  962         len = auio.uio_resid;
  963         error = soreceive(so, &fromsa, &auio, NULL,
  964             (mp->msg_control || controlp) ? &control : NULL,
  965             &mp->msg_flags);
  966         if (error != 0) {
  967                 if (auio.uio_resid != len && (error == ERESTART ||
  968                     error == EINTR || error == EWOULDBLOCK))
  969                         error = 0;
  970         }
  971         if (fromsa != NULL)
  972                 AUDIT_ARG_SOCKADDR(td, AT_FDCWD, fromsa);
  973 #ifdef KTRACE
  974         if (ktruio != NULL) {
  975                 ktruio->uio_resid = len - auio.uio_resid;
  976                 ktrgenio(s, UIO_READ, ktruio, error);
  977         }
  978 #endif
  979         if (error != 0)
  980                 goto out;
  981         td->td_retval[0] = len - auio.uio_resid;
  982         if (mp->msg_name) {
  983                 len = mp->msg_namelen;
  984                 if (len <= 0 || fromsa == NULL)
  985                         len = 0;
  986                 else {
  987                         /* save sa_len before it is destroyed by MSG_COMPAT */
  988                         len = MIN(len, fromsa->sa_len);
  989 #ifdef COMPAT_OLDSOCK
  990                         if ((mp->msg_flags & MSG_COMPAT) != 0 &&
  991                             SV_PROC_FLAG(td->td_proc, SV_AOUT))
  992                                 ((struct osockaddr *)fromsa)->sa_family =
  993                                     fromsa->sa_family;
  994 #endif
  995                         if (fromseg == UIO_USERSPACE) {
  996                                 error = copyout(fromsa, mp->msg_name,
  997                                     (unsigned)len);
  998                                 if (error != 0)
  999                                         goto out;
 1000                         } else
 1001                                 bcopy(fromsa, mp->msg_name, len);
 1002                 }
 1003                 mp->msg_namelen = len;
 1004         }
 1005         if (mp->msg_control && controlp == NULL) {
 1006 #ifdef COMPAT_OLDSOCK
 1007                 /*
 1008                  * We assume that old recvmsg calls won't receive access
 1009                  * rights and other control info, esp. as control info
 1010                  * is always optional and those options didn't exist in 4.3.
 1011                  * If we receive rights, trim the cmsghdr; anything else
 1012                  * is tossed.
 1013                  */
 1014                 if (control && (mp->msg_flags & MSG_COMPAT) != 0 &&
 1015                     SV_PROC_FLAG(td->td_proc, SV_AOUT)) {
 1016                         if (mtod(control, struct cmsghdr *)->cmsg_level !=
 1017                             SOL_SOCKET ||
 1018                             mtod(control, struct cmsghdr *)->cmsg_type !=
 1019                             SCM_RIGHTS) {
 1020                                 mp->msg_controllen = 0;
 1021                                 goto out;
 1022                         }
 1023                         control->m_len -= sizeof (struct cmsghdr);
 1024                         control->m_data += sizeof (struct cmsghdr);
 1025                 }
 1026 #endif
 1027                 ctlbuf = mp->msg_control;
 1028                 len = mp->msg_controllen;
 1029                 mp->msg_controllen = 0;
 1030                 for (m = control; m != NULL && len >= m->m_len; m = m->m_next) {
 1031                         if ((error = copyout(mtod(m, caddr_t), ctlbuf,
 1032                             m->m_len)) != 0)
 1033                                 goto out;
 1034 
 1035                         ctlbuf += m->m_len;
 1036                         len -= m->m_len;
 1037                         mp->msg_controllen += m->m_len;
 1038                 }
 1039                 if (m != NULL) {
 1040                         mp->msg_flags |= MSG_CTRUNC;
 1041                         m_dispose_extcontrolm(m);
 1042                 }
 1043         }
 1044 out:
 1045         fdrop(fp, td);
 1046 #ifdef KTRACE
 1047         if (fromsa && KTRPOINT(td, KTR_STRUCT))
 1048                 ktrsockaddr(fromsa);
 1049 #endif
 1050         free(fromsa, M_SONAME);
 1051 
 1052         if (error == 0 && controlp != NULL)
 1053                 *controlp = control;
 1054         else if (control != NULL) {
 1055                 if (error != 0)
 1056                         m_dispose_extcontrolm(control);
 1057                 m_freem(control);
 1058         }
 1059 
 1060         return (error);
 1061 }
 1062 
 1063 static int
 1064 recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp)
 1065 {
 1066         int error;
 1067 
 1068         error = kern_recvit(td, s, mp, UIO_USERSPACE, NULL);
 1069         if (error != 0)
 1070                 return (error);
 1071         if (namelenp != NULL) {
 1072                 error = copyout(&mp->msg_namelen, namelenp, sizeof (socklen_t));
 1073 #ifdef COMPAT_OLDSOCK
 1074                 if ((mp->msg_flags & MSG_COMPAT) != 0 &&
 1075                     SV_PROC_FLAG(td->td_proc, SV_AOUT))
 1076                         error = 0;      /* old recvfrom didn't check */
 1077 #endif
 1078         }
 1079         return (error);
 1080 }
 1081 
 1082 int
 1083 sys_recvfrom(struct thread *td, struct recvfrom_args *uap)
 1084 {
 1085         struct msghdr msg;
 1086         struct iovec aiov;
 1087         int error;
 1088 
 1089         if (uap->fromlenaddr) {
 1090                 error = copyin(uap->fromlenaddr,
 1091                     &msg.msg_namelen, sizeof (msg.msg_namelen));
 1092                 if (error != 0)
 1093                         goto done2;
 1094         } else {
 1095                 msg.msg_namelen = 0;
 1096         }
 1097         msg.msg_name = uap->from;
 1098         msg.msg_iov = &aiov;
 1099         msg.msg_iovlen = 1;
 1100         aiov.iov_base = uap->buf;
 1101         aiov.iov_len = uap->len;
 1102         msg.msg_control = 0;
 1103         msg.msg_flags = uap->flags;
 1104         error = recvit(td, uap->s, &msg, uap->fromlenaddr);
 1105 done2:
 1106         return (error);
 1107 }
 1108 
 1109 #ifdef COMPAT_OLDSOCK
 1110 int
 1111 orecvfrom(struct thread *td, struct recvfrom_args *uap)
 1112 {
 1113 
 1114         uap->flags |= MSG_COMPAT;
 1115         return (sys_recvfrom(td, uap));
 1116 }
 1117 #endif
 1118 
 1119 #ifdef COMPAT_OLDSOCK
 1120 int
 1121 orecv(struct thread *td, struct orecv_args *uap)
 1122 {
 1123         struct msghdr msg;
 1124         struct iovec aiov;
 1125 
 1126         msg.msg_name = 0;
 1127         msg.msg_namelen = 0;
 1128         msg.msg_iov = &aiov;
 1129         msg.msg_iovlen = 1;
 1130         aiov.iov_base = uap->buf;
 1131         aiov.iov_len = uap->len;
 1132         msg.msg_control = 0;
 1133         msg.msg_flags = uap->flags;
 1134         return (recvit(td, uap->s, &msg, NULL));
 1135 }
 1136 
 1137 /*
 1138  * Old recvmsg.  This code takes advantage of the fact that the old msghdr
 1139  * overlays the new one, missing only the flags, and with the (old) access
 1140  * rights where the control fields are now.
 1141  */
 1142 int
 1143 orecvmsg(struct thread *td, struct orecvmsg_args *uap)
 1144 {
 1145         struct msghdr msg;
 1146         struct iovec *iov;
 1147         int error;
 1148 
 1149         error = copyin(uap->msg, &msg, sizeof (struct omsghdr));
 1150         if (error != 0)
 1151                 return (error);
 1152         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
 1153         if (error != 0)
 1154                 return (error);
 1155         msg.msg_flags = uap->flags | MSG_COMPAT;
 1156         msg.msg_iov = iov;
 1157         error = recvit(td, uap->s, &msg, &uap->msg->msg_namelen);
 1158         if (msg.msg_controllen && error == 0)
 1159                 error = copyout(&msg.msg_controllen,
 1160                     &uap->msg->msg_accrightslen, sizeof (int));
 1161         free(iov, M_IOV);
 1162         return (error);
 1163 }
 1164 #endif
 1165 
 1166 int
 1167 sys_recvmsg(struct thread *td, struct recvmsg_args *uap)
 1168 {
 1169         struct msghdr msg;
 1170         struct iovec *uiov, *iov;
 1171         int error;
 1172 
 1173         error = copyin(uap->msg, &msg, sizeof (msg));
 1174         if (error != 0)
 1175                 return (error);
 1176         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
 1177         if (error != 0)
 1178                 return (error);
 1179         msg.msg_flags = uap->flags;
 1180 #ifdef COMPAT_OLDSOCK
 1181         if (SV_PROC_FLAG(td->td_proc, SV_AOUT))
 1182                 msg.msg_flags &= ~MSG_COMPAT;
 1183 #endif
 1184         uiov = msg.msg_iov;
 1185         msg.msg_iov = iov;
 1186         error = recvit(td, uap->s, &msg, NULL);
 1187         if (error == 0) {
 1188                 msg.msg_iov = uiov;
 1189                 error = copyout(&msg, uap->msg, sizeof(msg));
 1190         }
 1191         free(iov, M_IOV);
 1192         return (error);
 1193 }
 1194 
 1195 int
 1196 sys_shutdown(struct thread *td, struct shutdown_args *uap)
 1197 {
 1198 
 1199         return (kern_shutdown(td, uap->s, uap->how));
 1200 }
 1201 
 1202 int
 1203 kern_shutdown(struct thread *td, int s, int how)
 1204 {
 1205         struct socket *so;
 1206         struct file *fp;
 1207         int error;
 1208 
 1209         AUDIT_ARG_FD(s);
 1210         error = getsock_cap(td, s, &cap_shutdown_rights,
 1211             &fp, NULL, NULL);
 1212         if (error == 0) {
 1213                 so = fp->f_data;
 1214                 error = soshutdown(so, how);
 1215                 /*
 1216                  * Previous versions did not return ENOTCONN, but 0 in
 1217                  * case the socket was not connected. Some important
 1218                  * programs like syslogd up to r279016, 2015-02-19,
 1219                  * still depend on this behavior.
 1220                  */
 1221                 if (error == ENOTCONN &&
 1222                     td->td_proc->p_osrel < P_OSREL_SHUTDOWN_ENOTCONN)
 1223                         error = 0;
 1224                 fdrop(fp, td);
 1225         }
 1226         return (error);
 1227 }
 1228 
 1229 int
 1230 sys_setsockopt(struct thread *td, struct setsockopt_args *uap)
 1231 {
 1232 
 1233         return (kern_setsockopt(td, uap->s, uap->level, uap->name,
 1234             uap->val, UIO_USERSPACE, uap->valsize));
 1235 }
 1236 
 1237 int
 1238 kern_setsockopt(struct thread *td, int s, int level, int name, void *val,
 1239     enum uio_seg valseg, socklen_t valsize)
 1240 {
 1241         struct socket *so;
 1242         struct file *fp;
 1243         struct sockopt sopt;
 1244         int error;
 1245 
 1246         if (val == NULL && valsize != 0)
 1247                 return (EFAULT);
 1248         if ((int)valsize < 0)
 1249                 return (EINVAL);
 1250 
 1251         sopt.sopt_dir = SOPT_SET;
 1252         sopt.sopt_level = level;
 1253         sopt.sopt_name = name;
 1254         sopt.sopt_val = val;
 1255         sopt.sopt_valsize = valsize;
 1256         switch (valseg) {
 1257         case UIO_USERSPACE:
 1258                 sopt.sopt_td = td;
 1259                 break;
 1260         case UIO_SYSSPACE:
 1261                 sopt.sopt_td = NULL;
 1262                 break;
 1263         default:
 1264                 panic("kern_setsockopt called with bad valseg");
 1265         }
 1266 
 1267         AUDIT_ARG_FD(s);
 1268         error = getsock_cap(td, s, &cap_setsockopt_rights,
 1269             &fp, NULL, NULL);
 1270         if (error == 0) {
 1271                 so = fp->f_data;
 1272                 error = sosetopt(so, &sopt);
 1273                 fdrop(fp, td);
 1274         }
 1275         return(error);
 1276 }
 1277 
 1278 int
 1279 sys_getsockopt(struct thread *td, struct getsockopt_args *uap)
 1280 {
 1281         socklen_t valsize;
 1282         int error;
 1283 
 1284         if (uap->val) {
 1285                 error = copyin(uap->avalsize, &valsize, sizeof (valsize));
 1286                 if (error != 0)
 1287                         return (error);
 1288         }
 1289 
 1290         error = kern_getsockopt(td, uap->s, uap->level, uap->name,
 1291             uap->val, UIO_USERSPACE, &valsize);
 1292 
 1293         if (error == 0)
 1294                 error = copyout(&valsize, uap->avalsize, sizeof (valsize));
 1295         return (error);
 1296 }
 1297 
 1298 /*
 1299  * Kernel version of getsockopt.
 1300  * optval can be a userland or userspace. optlen is always a kernel pointer.
 1301  */
 1302 int
 1303 kern_getsockopt(struct thread *td, int s, int level, int name, void *val,
 1304     enum uio_seg valseg, socklen_t *valsize)
 1305 {
 1306         struct socket *so;
 1307         struct file *fp;
 1308         struct sockopt sopt;
 1309         int error;
 1310 
 1311         if (val == NULL)
 1312                 *valsize = 0;
 1313         if ((int)*valsize < 0)
 1314                 return (EINVAL);
 1315 
 1316         sopt.sopt_dir = SOPT_GET;
 1317         sopt.sopt_level = level;
 1318         sopt.sopt_name = name;
 1319         sopt.sopt_val = val;
 1320         sopt.sopt_valsize = (size_t)*valsize; /* checked non-negative above */
 1321         switch (valseg) {
 1322         case UIO_USERSPACE:
 1323                 sopt.sopt_td = td;
 1324                 break;
 1325         case UIO_SYSSPACE:
 1326                 sopt.sopt_td = NULL;
 1327                 break;
 1328         default:
 1329                 panic("kern_getsockopt called with bad valseg");
 1330         }
 1331 
 1332         AUDIT_ARG_FD(s);
 1333         error = getsock_cap(td, s, &cap_getsockopt_rights,
 1334             &fp, NULL, NULL);
 1335         if (error == 0) {
 1336                 so = fp->f_data;
 1337                 error = sogetopt(so, &sopt);
 1338                 *valsize = sopt.sopt_valsize;
 1339                 fdrop(fp, td);
 1340         }
 1341         return (error);
 1342 }
 1343 
 1344 /*
 1345  * getsockname1() - Get socket name.
 1346  */
 1347 static int
 1348 getsockname1(struct thread *td, struct getsockname_args *uap, int compat)
 1349 {
 1350         struct sockaddr *sa;
 1351         socklen_t len;
 1352         int error;
 1353 
 1354         error = copyin(uap->alen, &len, sizeof(len));
 1355         if (error != 0)
 1356                 return (error);
 1357 
 1358         error = kern_getsockname(td, uap->fdes, &sa, &len);
 1359         if (error != 0)
 1360                 return (error);
 1361 
 1362         if (len != 0) {
 1363 #ifdef COMPAT_OLDSOCK
 1364                 if (compat && SV_PROC_FLAG(td->td_proc, SV_AOUT))
 1365                         ((struct osockaddr *)sa)->sa_family = sa->sa_family;
 1366 #endif
 1367                 error = copyout(sa, uap->asa, (u_int)len);
 1368         }
 1369         free(sa, M_SONAME);
 1370         if (error == 0)
 1371                 error = copyout(&len, uap->alen, sizeof(len));
 1372         return (error);
 1373 }
 1374 
 1375 int
 1376 kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
 1377     socklen_t *alen)
 1378 {
 1379         struct socket *so;
 1380         struct file *fp;
 1381         socklen_t len;
 1382         int error;
 1383 
 1384         AUDIT_ARG_FD(fd);
 1385         error = getsock_cap(td, fd, &cap_getsockname_rights,
 1386             &fp, NULL, NULL);
 1387         if (error != 0)
 1388                 return (error);
 1389         so = fp->f_data;
 1390         *sa = NULL;
 1391         CURVNET_SET(so->so_vnet);
 1392         error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, sa);
 1393         CURVNET_RESTORE();
 1394         if (error != 0)
 1395                 goto bad;
 1396         if (*sa == NULL)
 1397                 len = 0;
 1398         else
 1399                 len = MIN(*alen, (*sa)->sa_len);
 1400         *alen = len;
 1401 #ifdef KTRACE
 1402         if (KTRPOINT(td, KTR_STRUCT))
 1403                 ktrsockaddr(*sa);
 1404 #endif
 1405 bad:
 1406         fdrop(fp, td);
 1407         if (error != 0 && *sa != NULL) {
 1408                 free(*sa, M_SONAME);
 1409                 *sa = NULL;
 1410         }
 1411         return (error);
 1412 }
 1413 
 1414 int
 1415 sys_getsockname(struct thread *td, struct getsockname_args *uap)
 1416 {
 1417 
 1418         return (getsockname1(td, uap, 0));
 1419 }
 1420 
 1421 #ifdef COMPAT_OLDSOCK
 1422 int
 1423 ogetsockname(struct thread *td, struct getsockname_args *uap)
 1424 {
 1425 
 1426         return (getsockname1(td, uap, 1));
 1427 }
 1428 #endif /* COMPAT_OLDSOCK */
 1429 
 1430 /*
 1431  * getpeername1() - Get name of peer for connected socket.
 1432  */
 1433 static int
 1434 getpeername1(struct thread *td, struct getpeername_args *uap, int compat)
 1435 {
 1436         struct sockaddr *sa;
 1437         socklen_t len;
 1438         int error;
 1439 
 1440         error = copyin(uap->alen, &len, sizeof (len));
 1441         if (error != 0)
 1442                 return (error);
 1443 
 1444         error = kern_getpeername(td, uap->fdes, &sa, &len);
 1445         if (error != 0)
 1446                 return (error);
 1447 
 1448         if (len != 0) {
 1449 #ifdef COMPAT_OLDSOCK
 1450                 if (compat && SV_PROC_FLAG(td->td_proc, SV_AOUT))
 1451                         ((struct osockaddr *)sa)->sa_family = sa->sa_family;
 1452 #endif
 1453                 error = copyout(sa, uap->asa, (u_int)len);
 1454         }
 1455         free(sa, M_SONAME);
 1456         if (error == 0)
 1457                 error = copyout(&len, uap->alen, sizeof(len));
 1458         return (error);
 1459 }
 1460 
 1461 int
 1462 kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
 1463     socklen_t *alen)
 1464 {
 1465         struct socket *so;
 1466         struct file *fp;
 1467         socklen_t len;
 1468         int error;
 1469 
 1470         AUDIT_ARG_FD(fd);
 1471         error = getsock_cap(td, fd, &cap_getpeername_rights,
 1472             &fp, NULL, NULL);
 1473         if (error != 0)
 1474                 return (error);
 1475         so = fp->f_data;
 1476         if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) {
 1477                 error = ENOTCONN;
 1478                 goto done;
 1479         }
 1480         *sa = NULL;
 1481         CURVNET_SET(so->so_vnet);
 1482         error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, sa);
 1483         CURVNET_RESTORE();
 1484         if (error != 0)
 1485                 goto bad;
 1486         if (*sa == NULL)
 1487                 len = 0;
 1488         else
 1489                 len = MIN(*alen, (*sa)->sa_len);
 1490         *alen = len;
 1491 #ifdef KTRACE
 1492         if (KTRPOINT(td, KTR_STRUCT))
 1493                 ktrsockaddr(*sa);
 1494 #endif
 1495 bad:
 1496         if (error != 0 && *sa != NULL) {
 1497                 free(*sa, M_SONAME);
 1498                 *sa = NULL;
 1499         }
 1500 done:
 1501         fdrop(fp, td);
 1502         return (error);
 1503 }
 1504 
 1505 int
 1506 sys_getpeername(struct thread *td, struct getpeername_args *uap)
 1507 {
 1508 
 1509         return (getpeername1(td, uap, 0));
 1510 }
 1511 
 1512 #ifdef COMPAT_OLDSOCK
 1513 int
 1514 ogetpeername(struct thread *td, struct ogetpeername_args *uap)
 1515 {
 1516 
 1517         /* XXX uap should have type `getpeername_args *' to begin with. */
 1518         return (getpeername1(td, (struct getpeername_args *)uap, 1));
 1519 }
 1520 #endif /* COMPAT_OLDSOCK */
 1521 
 1522 static int
 1523 sockargs(struct mbuf **mp, char *buf, socklen_t buflen, int type)
 1524 {
 1525         struct sockaddr *sa;
 1526         struct mbuf *m;
 1527         int error;
 1528 
 1529         if (buflen > MLEN) {
 1530 #ifdef COMPAT_OLDSOCK
 1531                 if (type == MT_SONAME && buflen <= 112 &&
 1532                     SV_CURPROC_FLAG(SV_AOUT))
 1533                         buflen = MLEN;          /* unix domain compat. hack */
 1534                 else
 1535 #endif
 1536                         if (buflen > MCLBYTES)
 1537                                 return (EINVAL);
 1538         }
 1539         m = m_get2(buflen, M_WAITOK, type, 0);
 1540         m->m_len = buflen;
 1541         error = copyin(buf, mtod(m, void *), buflen);
 1542         if (error != 0)
 1543                 (void) m_free(m);
 1544         else {
 1545                 *mp = m;
 1546                 if (type == MT_SONAME) {
 1547                         sa = mtod(m, struct sockaddr *);
 1548 
 1549 #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
 1550                         if (sa->sa_family == 0 && sa->sa_len < AF_MAX &&
 1551                             SV_CURPROC_FLAG(SV_AOUT))
 1552                                 sa->sa_family = sa->sa_len;
 1553 #endif
 1554                         sa->sa_len = buflen;
 1555                 }
 1556         }
 1557         return (error);
 1558 }
 1559 
 1560 int
 1561 getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len)
 1562 {
 1563         struct sockaddr *sa;
 1564         int error;
 1565 
 1566         if (len > SOCK_MAXADDRLEN)
 1567                 return (ENAMETOOLONG);
 1568         if (len < offsetof(struct sockaddr, sa_data[0]))
 1569                 return (EINVAL);
 1570         sa = malloc(len, M_SONAME, M_WAITOK);
 1571         error = copyin(uaddr, sa, len);
 1572         if (error != 0) {
 1573                 free(sa, M_SONAME);
 1574         } else {
 1575 #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
 1576                 if (sa->sa_family == 0 && sa->sa_len < AF_MAX &&
 1577                     SV_CURPROC_FLAG(SV_AOUT))
 1578                         sa->sa_family = sa->sa_len;
 1579 #endif
 1580                 sa->sa_len = len;
 1581                 *namp = sa;
 1582         }
 1583         return (error);
 1584 }
 1585 
 1586 /*
 1587  * Dispose of externalized rights from an SCM_RIGHTS message.  This function
 1588  * should be used in error or truncation cases to avoid leaking file descriptors
 1589  * into the recipient's (the current thread's) table.
 1590  */
 1591 void
 1592 m_dispose_extcontrolm(struct mbuf *m)
 1593 {
 1594         struct cmsghdr *cm;
 1595         struct file *fp;
 1596         struct thread *td;
 1597         socklen_t clen, datalen;
 1598         int error, fd, *fds, nfd;
 1599 
 1600         td = curthread;
 1601         for (; m != NULL; m = m->m_next) {
 1602                 if (m->m_type != MT_EXTCONTROL)
 1603                         continue;
 1604                 cm = mtod(m, struct cmsghdr *);
 1605                 clen = m->m_len;
 1606                 while (clen > 0) {
 1607                         if (clen < sizeof(*cm))
 1608                                 panic("%s: truncated mbuf %p", __func__, m);
 1609                         datalen = CMSG_SPACE(cm->cmsg_len - CMSG_SPACE(0));
 1610                         if (clen < datalen)
 1611                                 panic("%s: truncated mbuf %p", __func__, m);
 1612 
 1613                         if (cm->cmsg_level == SOL_SOCKET &&
 1614                             cm->cmsg_type == SCM_RIGHTS) {
 1615                                 fds = (int *)CMSG_DATA(cm);
 1616                                 nfd = (cm->cmsg_len - CMSG_SPACE(0)) /
 1617                                     sizeof(int);
 1618 
 1619                                 while (nfd-- > 0) {
 1620                                         fd = *fds++;
 1621                                         error = fget(td, fd, &cap_no_rights,
 1622                                             &fp);
 1623                                         if (error == 0) {
 1624                                                 fdclose(td, fp, fd);
 1625                                                 fdrop(fp, td);
 1626                                         }
 1627                                 }
 1628                         }
 1629                         clen -= datalen;
 1630                         cm = (struct cmsghdr *)((uint8_t *)cm + datalen);
 1631                 }
 1632                 m_chtype(m, MT_CONTROL);
 1633         }
 1634 }

Cache object: 836d6e09b5e9975b0eadf1004baa1382


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