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