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