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


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

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

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

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

Cache object: 12c598339283152d9c813877618f3d4a


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