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