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