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