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