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