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