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