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