]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/uipc_syscalls.c
Eliminate the overhead of gratuitous repeated reinitialization of cap_rights
[FreeBSD/FreeBSD.git] / sys / kern / uipc_syscalls.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 1982, 1986, 1989, 1990, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  *      @(#)uipc_syscalls.c     8.4 (Berkeley) 2/21/94
32  */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include "opt_capsicum.h"
38 #include "opt_inet.h"
39 #include "opt_inet6.h"
40 #include "opt_ktrace.h"
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/capsicum.h>
45 #include <sys/kernel.h>
46 #include <sys/lock.h>
47 #include <sys/mutex.h>
48 #include <sys/sysproto.h>
49 #include <sys/malloc.h>
50 #include <sys/filedesc.h>
51 #include <sys/proc.h>
52 #include <sys/filio.h>
53 #include <sys/jail.h>
54 #include <sys/mbuf.h>
55 #include <sys/protosw.h>
56 #include <sys/rwlock.h>
57 #include <sys/socket.h>
58 #include <sys/socketvar.h>
59 #include <sys/syscallsubr.h>
60 #include <sys/uio.h>
61 #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         int error;
188
189 #ifdef CAPABILITY_MODE
190         if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD))
191                 return (ECAPMODE);
192 #endif
193
194         AUDIT_ARG_FD(fd);
195         AUDIT_ARG_SOCKADDR(td, dirfd, sa);
196         error = getsock_cap(td, fd, &cap_bind_rights,
197             &fp, NULL, NULL);
198         if (error != 0)
199                 return (error);
200         so = fp->f_data;
201 #ifdef KTRACE
202         if (KTRPOINT(td, KTR_STRUCT))
203                 ktrsockaddr(sa);
204 #endif
205 #ifdef MAC
206         error = mac_socket_check_bind(td->td_ucred, so, sa);
207         if (error == 0) {
208 #endif
209                 if (dirfd == AT_FDCWD)
210                         error = sobind(so, sa, td);
211                 else
212                         error = sobindat(dirfd, so, sa, td);
213 #ifdef MAC
214         }
215 #endif
216         fdrop(fp, td);
217         return (error);
218 }
219
220 int
221 sys_bindat(struct thread *td, struct bindat_args *uap)
222 {
223         struct sockaddr *sa;
224         int error;
225
226         error = getsockaddr(&sa, uap->name, uap->namelen);
227         if (error == 0) {
228                 error = kern_bindat(td, uap->fd, uap->s, sa);
229                 free(sa, M_SONAME);
230         }
231         return (error);
232 }
233
234 int
235 sys_listen(struct thread *td, struct listen_args *uap)
236 {
237
238         return (kern_listen(td, uap->s, uap->backlog));
239 }
240
241 int
242 kern_listen(struct thread *td, int s, int backlog)
243 {
244         struct socket *so;
245         struct file *fp;
246         int error;
247
248         AUDIT_ARG_FD(s);
249         error = getsock_cap(td, s, &cap_listen_rights,
250             &fp, NULL, NULL);
251         if (error == 0) {
252                 so = fp->f_data;
253 #ifdef MAC
254                 error = mac_socket_check_listen(td->td_ucred, so);
255                 if (error == 0)
256 #endif
257                         error = solisten(so, backlog, td);
258                 fdrop(fp, td);
259         }
260         return (error);
261 }
262
263 /*
264  * accept1()
265  */
266 static int
267 accept1(td, s, uname, anamelen, flags)
268         struct thread *td;
269         int s;
270         struct sockaddr *uname;
271         socklen_t *anamelen;
272         int flags;
273 {
274         struct sockaddr *name;
275         socklen_t namelen;
276         struct file *fp;
277         int error;
278
279         if (uname == NULL)
280                 return (kern_accept4(td, s, NULL, NULL, flags, NULL));
281
282         error = copyin(anamelen, &namelen, sizeof (namelen));
283         if (error != 0)
284                 return (error);
285
286         error = kern_accept4(td, s, &name, &namelen, flags, &fp);
287
288         if (error != 0)
289                 return (error);
290
291         if (error == 0 && uname != NULL) {
292 #ifdef COMPAT_OLDSOCK
293                 if (flags & ACCEPT4_COMPAT)
294                         ((struct osockaddr *)name)->sa_family =
295                             name->sa_family;
296 #endif
297                 error = copyout(name, uname, namelen);
298         }
299         if (error == 0)
300                 error = copyout(&namelen, anamelen,
301                     sizeof(namelen));
302         if (error != 0)
303                 fdclose(td, fp, td->td_retval[0]);
304         fdrop(fp, td);
305         free(name, M_SONAME);
306         return (error);
307 }
308
309 int
310 kern_accept(struct thread *td, int s, struct sockaddr **name,
311     socklen_t *namelen, struct file **fp)
312 {
313         return (kern_accept4(td, s, name, namelen, ACCEPT4_INHERIT, fp));
314 }
315
316 int
317 kern_accept4(struct thread *td, int s, struct sockaddr **name,
318     socklen_t *namelen, int flags, struct file **fp)
319 {
320         struct file *headfp, *nfp = NULL;
321         struct sockaddr *sa = NULL;
322         struct socket *head, *so;
323         struct filecaps fcaps;
324         u_int fflag;
325         pid_t pgid;
326         int error, fd, tmp;
327
328         if (name != NULL)
329                 *name = NULL;
330
331         AUDIT_ARG_FD(s);
332         error = getsock_cap(td, s, &cap_accept_rights,
333             &headfp, &fflag, &fcaps);
334         if (error != 0)
335                 return (error);
336         head = headfp->f_data;
337         if ((head->so_options & SO_ACCEPTCONN) == 0) {
338                 error = EINVAL;
339                 goto done;
340         }
341 #ifdef MAC
342         error = mac_socket_check_accept(td->td_ucred, head);
343         if (error != 0)
344                 goto done;
345 #endif
346         error = falloc_caps(td, &nfp, &fd,
347             (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0, &fcaps);
348         if (error != 0)
349                 goto done;
350         SOCK_LOCK(head);
351         if (!SOLISTENING(head)) {
352                 SOCK_UNLOCK(head);
353                 error = EINVAL;
354                 goto noconnection;
355         }
356
357         error = solisten_dequeue(head, &so, flags);
358         if (error != 0)
359                 goto noconnection;
360
361         /* An extra reference on `nfp' has been held for us by falloc(). */
362         td->td_retval[0] = fd;
363
364         /* Connection has been removed from the listen queue. */
365         KNOTE_UNLOCKED(&head->so_rdsel.si_note, 0);
366
367         if (flags & ACCEPT4_INHERIT) {
368                 pgid = fgetown(&head->so_sigio);
369                 if (pgid != 0)
370                         fsetown(pgid, &so->so_sigio);
371         } else {
372                 fflag &= ~(FNONBLOCK | FASYNC);
373                 if (flags & SOCK_NONBLOCK)
374                         fflag |= FNONBLOCK;
375         }
376
377         finit(nfp, fflag, DTYPE_SOCKET, so, &socketops);
378         /* Sync socket nonblocking/async state with file flags */
379         tmp = fflag & FNONBLOCK;
380         (void) fo_ioctl(nfp, FIONBIO, &tmp, td->td_ucred, td);
381         tmp = fflag & FASYNC;
382         (void) fo_ioctl(nfp, FIOASYNC, &tmp, td->td_ucred, td);
383         error = soaccept(so, &sa);
384         if (error != 0)
385                 goto noconnection;
386         if (sa == NULL) {
387                 if (name)
388                         *namelen = 0;
389                 goto done;
390         }
391         AUDIT_ARG_SOCKADDR(td, AT_FDCWD, sa);
392         if (name) {
393                 /* check sa_len before it is destroyed */
394                 if (*namelen > sa->sa_len)
395                         *namelen = sa->sa_len;
396 #ifdef KTRACE
397                 if (KTRPOINT(td, KTR_STRUCT))
398                         ktrsockaddr(sa);
399 #endif
400                 *name = sa;
401                 sa = NULL;
402         }
403 noconnection:
404         free(sa, M_SONAME);
405
406         /*
407          * close the new descriptor, assuming someone hasn't ripped it
408          * out from under us.
409          */
410         if (error != 0)
411                 fdclose(td, nfp, fd);
412
413         /*
414          * Release explicitly held references before returning.  We return
415          * a reference on nfp to the caller on success if they request it.
416          */
417 done:
418         if (nfp == NULL)
419                 filecaps_free(&fcaps);
420         if (fp != NULL) {
421                 if (error == 0) {
422                         *fp = nfp;
423                         nfp = NULL;
424                 } else
425                         *fp = NULL;
426         }
427         if (nfp != NULL)
428                 fdrop(nfp, td);
429         fdrop(headfp, td);
430         return (error);
431 }
432
433 int
434 sys_accept(td, uap)
435         struct thread *td;
436         struct accept_args *uap;
437 {
438
439         return (accept1(td, uap->s, uap->name, uap->anamelen, ACCEPT4_INHERIT));
440 }
441
442 int
443 sys_accept4(td, uap)
444         struct thread *td;
445         struct accept4_args *uap;
446 {
447
448         if (uap->flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
449                 return (EINVAL);
450
451         return (accept1(td, uap->s, uap->name, uap->anamelen, uap->flags));
452 }
453
454 #ifdef COMPAT_OLDSOCK
455 int
456 oaccept(td, uap)
457         struct thread *td;
458         struct accept_args *uap;
459 {
460
461         return (accept1(td, uap->s, uap->name, uap->anamelen,
462             ACCEPT4_INHERIT | ACCEPT4_COMPAT));
463 }
464 #endif /* COMPAT_OLDSOCK */
465
466 int
467 sys_connect(struct thread *td, struct connect_args *uap)
468 {
469         struct sockaddr *sa;
470         int error;
471
472         error = getsockaddr(&sa, uap->name, uap->namelen);
473         if (error == 0) {
474                 error = kern_connectat(td, AT_FDCWD, uap->s, sa);
475                 free(sa, M_SONAME);
476         }
477         return (error);
478 }
479
480 int
481 kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
482 {
483         struct socket *so;
484         struct file *fp;
485         int error, interrupted = 0;
486
487 #ifdef CAPABILITY_MODE
488         if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD))
489                 return (ECAPMODE);
490 #endif
491
492         AUDIT_ARG_FD(fd);
493         AUDIT_ARG_SOCKADDR(td, dirfd, sa);
494         error = getsock_cap(td, fd, &cap_connect_rights,
495             &fp, NULL, NULL);
496         if (error != 0)
497                 return (error);
498         so = fp->f_data;
499         if (so->so_state & SS_ISCONNECTING) {
500                 error = EALREADY;
501                 goto done1;
502         }
503 #ifdef KTRACE
504         if (KTRPOINT(td, KTR_STRUCT))
505                 ktrsockaddr(sa);
506 #endif
507 #ifdef MAC
508         error = mac_socket_check_connect(td->td_ucred, so, sa);
509         if (error != 0)
510                 goto bad;
511 #endif
512         if (dirfd == AT_FDCWD)
513                 error = soconnect(so, sa, td);
514         else
515                 error = soconnectat(dirfd, so, sa, td);
516         if (error != 0)
517                 goto bad;
518         if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
519                 error = EINPROGRESS;
520                 goto done1;
521         }
522         SOCK_LOCK(so);
523         while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
524                 error = msleep(&so->so_timeo, &so->so_lock, PSOCK | PCATCH,
525                     "connec", 0);
526                 if (error != 0) {
527                         if (error == EINTR || error == ERESTART)
528                                 interrupted = 1;
529                         break;
530                 }
531         }
532         if (error == 0) {
533                 error = so->so_error;
534                 so->so_error = 0;
535         }
536         SOCK_UNLOCK(so);
537 bad:
538         if (!interrupted)
539                 so->so_state &= ~SS_ISCONNECTING;
540         if (error == ERESTART)
541                 error = EINTR;
542 done1:
543         fdrop(fp, td);
544         return (error);
545 }
546
547 int
548 sys_connectat(struct thread *td, struct connectat_args *uap)
549 {
550         struct sockaddr *sa;
551         int error;
552
553         error = getsockaddr(&sa, uap->name, uap->namelen);
554         if (error == 0) {
555                 error = kern_connectat(td, uap->fd, uap->s, sa);
556                 free(sa, M_SONAME);
557         }
558         return (error);
559 }
560
561 int
562 kern_socketpair(struct thread *td, int domain, int type, int protocol,
563     int *rsv)
564 {
565         struct file *fp1, *fp2;
566         struct socket *so1, *so2;
567         int fd, error, oflag, fflag;
568
569         AUDIT_ARG_SOCKET(domain, type, protocol);
570
571         oflag = 0;
572         fflag = 0;
573         if ((type & SOCK_CLOEXEC) != 0) {
574                 type &= ~SOCK_CLOEXEC;
575                 oflag |= O_CLOEXEC;
576         }
577         if ((type & SOCK_NONBLOCK) != 0) {
578                 type &= ~SOCK_NONBLOCK;
579                 fflag |= FNONBLOCK;
580         }
581 #ifdef MAC
582         /* We might want to have a separate check for socket pairs. */
583         error = mac_socket_check_create(td->td_ucred, domain, type,
584             protocol);
585         if (error != 0)
586                 return (error);
587 #endif
588         error = socreate(domain, &so1, type, protocol, td->td_ucred, td);
589         if (error != 0)
590                 return (error);
591         error = socreate(domain, &so2, type, protocol, td->td_ucred, td);
592         if (error != 0)
593                 goto free1;
594         /* On success extra reference to `fp1' and 'fp2' is set by falloc. */
595         error = falloc(td, &fp1, &fd, oflag);
596         if (error != 0)
597                 goto free2;
598         rsv[0] = fd;
599         fp1->f_data = so1;      /* so1 already has ref count */
600         error = falloc(td, &fp2, &fd, oflag);
601         if (error != 0)
602                 goto free3;
603         fp2->f_data = so2;      /* so2 already has ref count */
604         rsv[1] = fd;
605         error = soconnect2(so1, so2);
606         if (error != 0)
607                 goto free4;
608         if (type == SOCK_DGRAM) {
609                 /*
610                  * Datagram socket connection is asymmetric.
611                  */
612                  error = soconnect2(so2, so1);
613                  if (error != 0)
614                         goto free4;
615         }
616         finit(fp1, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp1->f_data,
617             &socketops);
618         finit(fp2, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp2->f_data,
619             &socketops);
620         if ((fflag & FNONBLOCK) != 0) {
621                 (void) fo_ioctl(fp1, FIONBIO, &fflag, td->td_ucred, td);
622                 (void) fo_ioctl(fp2, FIONBIO, &fflag, td->td_ucred, td);
623         }
624         fdrop(fp1, td);
625         fdrop(fp2, td);
626         return (0);
627 free4:
628         fdclose(td, fp2, rsv[1]);
629         fdrop(fp2, td);
630 free3:
631         fdclose(td, fp1, rsv[0]);
632         fdrop(fp1, td);
633 free2:
634         if (so2 != NULL)
635                 (void)soclose(so2);
636 free1:
637         if (so1 != NULL)
638                 (void)soclose(so1);
639         return (error);
640 }
641
642 int
643 sys_socketpair(struct thread *td, struct socketpair_args *uap)
644 {
645         int error, sv[2];
646
647         error = kern_socketpair(td, uap->domain, uap->type,
648             uap->protocol, sv);
649         if (error != 0)
650                 return (error);
651         error = copyout(sv, uap->rsv, 2 * sizeof(int));
652         if (error != 0) {
653                 (void)kern_close(td, sv[0]);
654                 (void)kern_close(td, sv[1]);
655         }
656         return (error);
657 }
658
659 static int
660 sendit(struct thread *td, int s, struct msghdr *mp, int flags)
661 {
662         struct mbuf *control;
663         struct sockaddr *to;
664         int error;
665
666 #ifdef CAPABILITY_MODE
667         if (IN_CAPABILITY_MODE(td) && (mp->msg_name != NULL))
668                 return (ECAPMODE);
669 #endif
670
671         if (mp->msg_name != NULL) {
672                 error = getsockaddr(&to, mp->msg_name, mp->msg_namelen);
673                 if (error != 0) {
674                         to = NULL;
675                         goto bad;
676                 }
677                 mp->msg_name = to;
678         } else {
679                 to = NULL;
680         }
681
682         if (mp->msg_control) {
683                 if (mp->msg_controllen < sizeof(struct cmsghdr)
684 #ifdef COMPAT_OLDSOCK
685                     && mp->msg_flags != MSG_COMPAT
686 #endif
687                 ) {
688                         error = EINVAL;
689                         goto bad;
690                 }
691                 error = sockargs(&control, mp->msg_control,
692                     mp->msg_controllen, MT_CONTROL);
693                 if (error != 0)
694                         goto bad;
695 #ifdef COMPAT_OLDSOCK
696                 if (mp->msg_flags == MSG_COMPAT) {
697                         struct cmsghdr *cm;
698
699                         M_PREPEND(control, sizeof(*cm), M_WAITOK);
700                         cm = mtod(control, struct cmsghdr *);
701                         cm->cmsg_len = control->m_len;
702                         cm->cmsg_level = SOL_SOCKET;
703                         cm->cmsg_type = SCM_RIGHTS;
704                 }
705 #endif
706         } else {
707                 control = NULL;
708         }
709
710         error = kern_sendit(td, s, mp, flags, control, UIO_USERSPACE);
711
712 bad:
713         free(to, M_SONAME);
714         return (error);
715 }
716
717 int
718 kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
719     struct mbuf *control, enum uio_seg segflg)
720 {
721         struct file *fp;
722         struct uio auio;
723         struct iovec *iov;
724         struct socket *so;
725         cap_rights_t rights;
726 #ifdef KTRACE
727         struct uio *ktruio = NULL;
728 #endif
729         ssize_t len;
730         int i, error;
731
732         AUDIT_ARG_FD(s);
733         cap_rights_init(&rights, CAP_SEND);
734         if (mp->msg_name != NULL) {
735                 AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name);
736                 cap_rights_set(&rights, CAP_CONNECT);
737         }
738         error = getsock_cap(td, s, &rights, &fp, NULL, NULL);
739         if (error != 0) {
740                 m_freem(control);
741                 return (error);
742         }
743         so = (struct socket *)fp->f_data;
744
745 #ifdef KTRACE
746         if (mp->msg_name != NULL && KTRPOINT(td, KTR_STRUCT))
747                 ktrsockaddr(mp->msg_name);
748 #endif
749 #ifdef MAC
750         if (mp->msg_name != NULL) {
751                 error = mac_socket_check_connect(td->td_ucred, so,
752                     mp->msg_name);
753                 if (error != 0) {
754                         m_freem(control);
755                         goto bad;
756                 }
757         }
758         error = mac_socket_check_send(td->td_ucred, so);
759         if (error != 0) {
760                 m_freem(control);
761                 goto bad;
762         }
763 #endif
764
765         auio.uio_iov = mp->msg_iov;
766         auio.uio_iovcnt = mp->msg_iovlen;
767         auio.uio_segflg = segflg;
768         auio.uio_rw = UIO_WRITE;
769         auio.uio_td = td;
770         auio.uio_offset = 0;                    /* XXX */
771         auio.uio_resid = 0;
772         iov = mp->msg_iov;
773         for (i = 0; i < mp->msg_iovlen; i++, iov++) {
774                 if ((auio.uio_resid += iov->iov_len) < 0) {
775                         error = EINVAL;
776                         m_freem(control);
777                         goto bad;
778                 }
779         }
780 #ifdef KTRACE
781         if (KTRPOINT(td, KTR_GENIO))
782                 ktruio = cloneuio(&auio);
783 #endif
784         len = auio.uio_resid;
785         error = sosend(so, mp->msg_name, &auio, 0, control, flags, td);
786         if (error != 0) {
787                 if (auio.uio_resid != len && (error == ERESTART ||
788                     error == EINTR || error == EWOULDBLOCK))
789                         error = 0;
790                 /* Generation of SIGPIPE can be controlled per socket */
791                 if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
792                     !(flags & MSG_NOSIGNAL)) {
793                         PROC_LOCK(td->td_proc);
794                         tdsignal(td, SIGPIPE);
795                         PROC_UNLOCK(td->td_proc);
796                 }
797         }
798         if (error == 0)
799                 td->td_retval[0] = len - auio.uio_resid;
800 #ifdef KTRACE
801         if (ktruio != NULL) {
802                 ktruio->uio_resid = td->td_retval[0];
803                 ktrgenio(s, UIO_WRITE, ktruio, error);
804         }
805 #endif
806 bad:
807         fdrop(fp, td);
808         return (error);
809 }
810
811 int
812 sys_sendto(struct thread *td, struct sendto_args *uap)
813 {
814         struct msghdr msg;
815         struct iovec aiov;
816
817         msg.msg_name = uap->to;
818         msg.msg_namelen = uap->tolen;
819         msg.msg_iov = &aiov;
820         msg.msg_iovlen = 1;
821         msg.msg_control = 0;
822 #ifdef COMPAT_OLDSOCK
823         msg.msg_flags = 0;
824 #endif
825         aiov.iov_base = uap->buf;
826         aiov.iov_len = uap->len;
827         return (sendit(td, uap->s, &msg, uap->flags));
828 }
829
830 #ifdef COMPAT_OLDSOCK
831 int
832 osend(struct thread *td, struct osend_args *uap)
833 {
834         struct msghdr msg;
835         struct iovec aiov;
836
837         msg.msg_name = 0;
838         msg.msg_namelen = 0;
839         msg.msg_iov = &aiov;
840         msg.msg_iovlen = 1;
841         aiov.iov_base = uap->buf;
842         aiov.iov_len = uap->len;
843         msg.msg_control = 0;
844         msg.msg_flags = 0;
845         return (sendit(td, uap->s, &msg, uap->flags));
846 }
847
848 int
849 osendmsg(struct thread *td, struct osendmsg_args *uap)
850 {
851         struct msghdr msg;
852         struct iovec *iov;
853         int error;
854
855         error = copyin(uap->msg, &msg, sizeof (struct omsghdr));
856         if (error != 0)
857                 return (error);
858         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
859         if (error != 0)
860                 return (error);
861         msg.msg_iov = iov;
862         msg.msg_flags = MSG_COMPAT;
863         error = sendit(td, uap->s, &msg, uap->flags);
864         free(iov, M_IOV);
865         return (error);
866 }
867 #endif
868
869 int
870 sys_sendmsg(struct thread *td, struct sendmsg_args *uap)
871 {
872         struct msghdr msg;
873         struct iovec *iov;
874         int error;
875
876         error = copyin(uap->msg, &msg, sizeof (msg));
877         if (error != 0)
878                 return (error);
879         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
880         if (error != 0)
881                 return (error);
882         msg.msg_iov = iov;
883 #ifdef COMPAT_OLDSOCK
884         msg.msg_flags = 0;
885 #endif
886         error = sendit(td, uap->s, &msg, uap->flags);
887         free(iov, M_IOV);
888         return (error);
889 }
890
891 int
892 kern_recvit(struct thread *td, int s, struct msghdr *mp, enum uio_seg fromseg,
893     struct mbuf **controlp)
894 {
895         struct uio auio;
896         struct iovec *iov;
897         struct mbuf *m, *control = NULL;
898         caddr_t ctlbuf;
899         struct file *fp;
900         struct socket *so;
901         struct sockaddr *fromsa = NULL;
902 #ifdef KTRACE
903         struct uio *ktruio = NULL;
904 #endif
905         ssize_t len;
906         int error, i;
907
908         if (controlp != NULL)
909                 *controlp = NULL;
910
911         AUDIT_ARG_FD(s);
912         error = getsock_cap(td, s, &cap_recv_rights,
913             &fp, NULL, NULL);
914         if (error != 0)
915                 return (error);
916         so = fp->f_data;
917
918 #ifdef MAC
919         error = mac_socket_check_receive(td->td_ucred, so);
920         if (error != 0) {
921                 fdrop(fp, td);
922                 return (error);
923         }
924 #endif
925
926         auio.uio_iov = mp->msg_iov;
927         auio.uio_iovcnt = mp->msg_iovlen;
928         auio.uio_segflg = UIO_USERSPACE;
929         auio.uio_rw = UIO_READ;
930         auio.uio_td = td;
931         auio.uio_offset = 0;                    /* XXX */
932         auio.uio_resid = 0;
933         iov = mp->msg_iov;
934         for (i = 0; i < mp->msg_iovlen; i++, iov++) {
935                 if ((auio.uio_resid += iov->iov_len) < 0) {
936                         fdrop(fp, td);
937                         return (EINVAL);
938                 }
939         }
940 #ifdef KTRACE
941         if (KTRPOINT(td, KTR_GENIO))
942                 ktruio = cloneuio(&auio);
943 #endif
944         len = auio.uio_resid;
945         error = soreceive(so, &fromsa, &auio, NULL,
946             (mp->msg_control || controlp) ? &control : NULL,
947             &mp->msg_flags);
948         if (error != 0) {
949                 if (auio.uio_resid != len && (error == ERESTART ||
950                     error == EINTR || error == EWOULDBLOCK))
951                         error = 0;
952         }
953         if (fromsa != NULL)
954                 AUDIT_ARG_SOCKADDR(td, AT_FDCWD, fromsa);
955 #ifdef KTRACE
956         if (ktruio != NULL) {
957                 ktruio->uio_resid = len - auio.uio_resid;
958                 ktrgenio(s, UIO_READ, ktruio, error);
959         }
960 #endif
961         if (error != 0)
962                 goto out;
963         td->td_retval[0] = len - auio.uio_resid;
964         if (mp->msg_name) {
965                 len = mp->msg_namelen;
966                 if (len <= 0 || fromsa == NULL)
967                         len = 0;
968                 else {
969                         /* save sa_len before it is destroyed by MSG_COMPAT */
970                         len = MIN(len, fromsa->sa_len);
971 #ifdef COMPAT_OLDSOCK
972                         if (mp->msg_flags & MSG_COMPAT)
973                                 ((struct osockaddr *)fromsa)->sa_family =
974                                     fromsa->sa_family;
975 #endif
976                         if (fromseg == UIO_USERSPACE) {
977                                 error = copyout(fromsa, mp->msg_name,
978                                     (unsigned)len);
979                                 if (error != 0)
980                                         goto out;
981                         } else
982                                 bcopy(fromsa, mp->msg_name, len);
983                 }
984                 mp->msg_namelen = len;
985         }
986         if (mp->msg_control && controlp == NULL) {
987 #ifdef COMPAT_OLDSOCK
988                 /*
989                  * We assume that old recvmsg calls won't receive access
990                  * rights and other control info, esp. as control info
991                  * is always optional and those options didn't exist in 4.3.
992                  * If we receive rights, trim the cmsghdr; anything else
993                  * is tossed.
994                  */
995                 if (control && mp->msg_flags & MSG_COMPAT) {
996                         if (mtod(control, struct cmsghdr *)->cmsg_level !=
997                             SOL_SOCKET ||
998                             mtod(control, struct cmsghdr *)->cmsg_type !=
999                             SCM_RIGHTS) {
1000                                 mp->msg_controllen = 0;
1001                                 goto out;
1002                         }
1003                         control->m_len -= sizeof (struct cmsghdr);
1004                         control->m_data += sizeof (struct cmsghdr);
1005                 }
1006 #endif
1007                 len = mp->msg_controllen;
1008                 m = control;
1009                 mp->msg_controllen = 0;
1010                 ctlbuf = mp->msg_control;
1011
1012                 while (m && len > 0) {
1013                         unsigned int tocopy;
1014
1015                         if (len >= m->m_len)
1016                                 tocopy = m->m_len;
1017                         else {
1018                                 mp->msg_flags |= MSG_CTRUNC;
1019                                 tocopy = len;
1020                         }
1021
1022                         if ((error = copyout(mtod(m, caddr_t),
1023                                         ctlbuf, tocopy)) != 0)
1024                                 goto out;
1025
1026                         ctlbuf += tocopy;
1027                         len -= tocopy;
1028                         m = m->m_next;
1029                 }
1030                 mp->msg_controllen = ctlbuf - (caddr_t)mp->msg_control;
1031         }
1032 out:
1033         fdrop(fp, td);
1034 #ifdef KTRACE
1035         if (fromsa && KTRPOINT(td, KTR_STRUCT))
1036                 ktrsockaddr(fromsa);
1037 #endif
1038         free(fromsa, M_SONAME);
1039
1040         if (error == 0 && controlp != NULL)
1041                 *controlp = control;
1042         else  if (control)
1043                 m_freem(control);
1044
1045         return (error);
1046 }
1047
1048 static int
1049 recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp)
1050 {
1051         int error;
1052
1053         error = kern_recvit(td, s, mp, UIO_USERSPACE, NULL);
1054         if (error != 0)
1055                 return (error);
1056         if (namelenp != NULL) {
1057                 error = copyout(&mp->msg_namelen, namelenp, sizeof (socklen_t));
1058 #ifdef COMPAT_OLDSOCK
1059                 if (mp->msg_flags & MSG_COMPAT)
1060                         error = 0;      /* old recvfrom didn't check */
1061 #endif
1062         }
1063         return (error);
1064 }
1065
1066 int
1067 sys_recvfrom(struct thread *td, struct recvfrom_args *uap)
1068 {
1069         struct msghdr msg;
1070         struct iovec aiov;
1071         int error;
1072
1073         if (uap->fromlenaddr) {
1074                 error = copyin(uap->fromlenaddr,
1075                     &msg.msg_namelen, sizeof (msg.msg_namelen));
1076                 if (error != 0)
1077                         goto done2;
1078         } else {
1079                 msg.msg_namelen = 0;
1080         }
1081         msg.msg_name = uap->from;
1082         msg.msg_iov = &aiov;
1083         msg.msg_iovlen = 1;
1084         aiov.iov_base = uap->buf;
1085         aiov.iov_len = uap->len;
1086         msg.msg_control = 0;
1087         msg.msg_flags = uap->flags;
1088         error = recvit(td, uap->s, &msg, uap->fromlenaddr);
1089 done2:
1090         return (error);
1091 }
1092
1093 #ifdef COMPAT_OLDSOCK
1094 int
1095 orecvfrom(struct thread *td, struct recvfrom_args *uap)
1096 {
1097
1098         uap->flags |= MSG_COMPAT;
1099         return (sys_recvfrom(td, uap));
1100 }
1101 #endif
1102
1103 #ifdef COMPAT_OLDSOCK
1104 int
1105 orecv(struct thread *td, struct orecv_args *uap)
1106 {
1107         struct msghdr msg;
1108         struct iovec aiov;
1109
1110         msg.msg_name = 0;
1111         msg.msg_namelen = 0;
1112         msg.msg_iov = &aiov;
1113         msg.msg_iovlen = 1;
1114         aiov.iov_base = uap->buf;
1115         aiov.iov_len = uap->len;
1116         msg.msg_control = 0;
1117         msg.msg_flags = uap->flags;
1118         return (recvit(td, uap->s, &msg, NULL));
1119 }
1120
1121 /*
1122  * Old recvmsg.  This code takes advantage of the fact that the old msghdr
1123  * overlays the new one, missing only the flags, and with the (old) access
1124  * rights where the control fields are now.
1125  */
1126 int
1127 orecvmsg(struct thread *td, struct orecvmsg_args *uap)
1128 {
1129         struct msghdr msg;
1130         struct iovec *iov;
1131         int error;
1132
1133         error = copyin(uap->msg, &msg, sizeof (struct omsghdr));
1134         if (error != 0)
1135                 return (error);
1136         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
1137         if (error != 0)
1138                 return (error);
1139         msg.msg_flags = uap->flags | MSG_COMPAT;
1140         msg.msg_iov = iov;
1141         error = recvit(td, uap->s, &msg, &uap->msg->msg_namelen);
1142         if (msg.msg_controllen && error == 0)
1143                 error = copyout(&msg.msg_controllen,
1144                     &uap->msg->msg_accrightslen, sizeof (int));
1145         free(iov, M_IOV);
1146         return (error);
1147 }
1148 #endif
1149
1150 int
1151 sys_recvmsg(struct thread *td, struct recvmsg_args *uap)
1152 {
1153         struct msghdr msg;
1154         struct iovec *uiov, *iov;
1155         int error;
1156
1157         error = copyin(uap->msg, &msg, sizeof (msg));
1158         if (error != 0)
1159                 return (error);
1160         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
1161         if (error != 0)
1162                 return (error);
1163         msg.msg_flags = uap->flags;
1164 #ifdef COMPAT_OLDSOCK
1165         msg.msg_flags &= ~MSG_COMPAT;
1166 #endif
1167         uiov = msg.msg_iov;
1168         msg.msg_iov = iov;
1169         error = recvit(td, uap->s, &msg, NULL);
1170         if (error == 0) {
1171                 msg.msg_iov = uiov;
1172                 error = copyout(&msg, uap->msg, sizeof(msg));
1173         }
1174         free(iov, M_IOV);
1175         return (error);
1176 }
1177
1178 int
1179 sys_shutdown(struct thread *td, struct shutdown_args *uap)
1180 {
1181
1182         return (kern_shutdown(td, uap->s, uap->how));
1183 }
1184
1185 int
1186 kern_shutdown(struct thread *td, int s, int how)
1187 {
1188         struct socket *so;
1189         struct file *fp;
1190         int error;
1191
1192         AUDIT_ARG_FD(s);
1193         error = getsock_cap(td, s, &cap_shutdown_rights,
1194             &fp, NULL, NULL);
1195         if (error == 0) {
1196                 so = fp->f_data;
1197                 error = soshutdown(so, how);
1198                 /*
1199                  * Previous versions did not return ENOTCONN, but 0 in
1200                  * case the socket was not connected. Some important
1201                  * programs like syslogd up to r279016, 2015-02-19,
1202                  * still depend on this behavior.
1203                  */
1204                 if (error == ENOTCONN &&
1205                     td->td_proc->p_osrel < P_OSREL_SHUTDOWN_ENOTCONN)
1206                         error = 0;
1207                 fdrop(fp, td);
1208         }
1209         return (error);
1210 }
1211
1212 int
1213 sys_setsockopt(struct thread *td, struct setsockopt_args *uap)
1214 {
1215
1216         return (kern_setsockopt(td, uap->s, uap->level, uap->name,
1217             uap->val, UIO_USERSPACE, uap->valsize));
1218 }
1219
1220 int
1221 kern_setsockopt(struct thread *td, int s, int level, int name, void *val,
1222     enum uio_seg valseg, socklen_t valsize)
1223 {
1224         struct socket *so;
1225         struct file *fp;
1226         struct sockopt sopt;
1227         int error;
1228
1229         if (val == NULL && valsize != 0)
1230                 return (EFAULT);
1231         if ((int)valsize < 0)
1232                 return (EINVAL);
1233
1234         sopt.sopt_dir = SOPT_SET;
1235         sopt.sopt_level = level;
1236         sopt.sopt_name = name;
1237         sopt.sopt_val = val;
1238         sopt.sopt_valsize = valsize;
1239         switch (valseg) {
1240         case UIO_USERSPACE:
1241                 sopt.sopt_td = td;
1242                 break;
1243         case UIO_SYSSPACE:
1244                 sopt.sopt_td = NULL;
1245                 break;
1246         default:
1247                 panic("kern_setsockopt called with bad valseg");
1248         }
1249
1250         AUDIT_ARG_FD(s);
1251         error = getsock_cap(td, s, &cap_setsockopt_rights,
1252             &fp, NULL, NULL);
1253         if (error == 0) {
1254                 so = fp->f_data;
1255                 error = sosetopt(so, &sopt);
1256                 fdrop(fp, td);
1257         }
1258         return(error);
1259 }
1260
1261 int
1262 sys_getsockopt(struct thread *td, struct getsockopt_args *uap)
1263 {
1264         socklen_t valsize;
1265         int error;
1266
1267         if (uap->val) {
1268                 error = copyin(uap->avalsize, &valsize, sizeof (valsize));
1269                 if (error != 0)
1270                         return (error);
1271         }
1272
1273         error = kern_getsockopt(td, uap->s, uap->level, uap->name,
1274             uap->val, UIO_USERSPACE, &valsize);
1275
1276         if (error == 0)
1277                 error = copyout(&valsize, uap->avalsize, sizeof (valsize));
1278         return (error);
1279 }
1280
1281 /*
1282  * Kernel version of getsockopt.
1283  * optval can be a userland or userspace. optlen is always a kernel pointer.
1284  */
1285 int
1286 kern_getsockopt(struct thread *td, int s, int level, int name, void *val,
1287     enum uio_seg valseg, socklen_t *valsize)
1288 {
1289         struct socket *so;
1290         struct file *fp;
1291         struct sockopt sopt;
1292         int error;
1293
1294         if (val == NULL)
1295                 *valsize = 0;
1296         if ((int)*valsize < 0)
1297                 return (EINVAL);
1298
1299         sopt.sopt_dir = SOPT_GET;
1300         sopt.sopt_level = level;
1301         sopt.sopt_name = name;
1302         sopt.sopt_val = val;
1303         sopt.sopt_valsize = (size_t)*valsize; /* checked non-negative above */
1304         switch (valseg) {
1305         case UIO_USERSPACE:
1306                 sopt.sopt_td = td;
1307                 break;
1308         case UIO_SYSSPACE:
1309                 sopt.sopt_td = NULL;
1310                 break;
1311         default:
1312                 panic("kern_getsockopt called with bad valseg");
1313         }
1314
1315         AUDIT_ARG_FD(s);
1316         error = getsock_cap(td, s, &cap_getsockopt_rights,
1317             &fp, NULL, NULL);
1318         if (error == 0) {
1319                 so = fp->f_data;
1320                 error = sogetopt(so, &sopt);
1321                 *valsize = sopt.sopt_valsize;
1322                 fdrop(fp, td);
1323         }
1324         return (error);
1325 }
1326
1327 /*
1328  * getsockname1() - Get socket name.
1329  */
1330 static int
1331 getsockname1(struct thread *td, struct getsockname_args *uap, int compat)
1332 {
1333         struct sockaddr *sa;
1334         socklen_t len;
1335         int error;
1336
1337         error = copyin(uap->alen, &len, sizeof(len));
1338         if (error != 0)
1339                 return (error);
1340
1341         error = kern_getsockname(td, uap->fdes, &sa, &len);
1342         if (error != 0)
1343                 return (error);
1344
1345         if (len != 0) {
1346 #ifdef COMPAT_OLDSOCK
1347                 if (compat)
1348                         ((struct osockaddr *)sa)->sa_family = sa->sa_family;
1349 #endif
1350                 error = copyout(sa, uap->asa, (u_int)len);
1351         }
1352         free(sa, M_SONAME);
1353         if (error == 0)
1354                 error = copyout(&len, uap->alen, sizeof(len));
1355         return (error);
1356 }
1357
1358 int
1359 kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
1360     socklen_t *alen)
1361 {
1362         struct socket *so;
1363         struct file *fp;
1364         socklen_t len;
1365         int error;
1366
1367         AUDIT_ARG_FD(fd);
1368         error = getsock_cap(td, fd, &cap_getsockname_rights,
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         socklen_t len;
1451         int error;
1452
1453         AUDIT_ARG_FD(fd);
1454         error = getsock_cap(td, fd, &cap_getpeername_rights,
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 }