uipc_syscalls.c revision 1.193 1 /* $NetBSD: uipc_syscalls.c,v 1.193 2018/05/03 21:43:33 christos Exp $ */
2
3 /*-
4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * Copyright (c) 1982, 1986, 1989, 1990, 1993
34 * The Regents of the University of California. All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 * @(#)uipc_syscalls.c 8.6 (Berkeley) 2/14/95
61 */
62
63 #include <sys/cdefs.h>
64 __KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.193 2018/05/03 21:43:33 christos Exp $");
65
66 #ifdef _KERNEL_OPT
67 #include "opt_pipe.h"
68 #endif
69
70 #include <sys/param.h>
71 #include <sys/systm.h>
72 #include <sys/filedesc.h>
73 #include <sys/proc.h>
74 #include <sys/file.h>
75 #include <sys/buf.h>
76 #include <sys/mbuf.h>
77 #include <sys/protosw.h>
78 #include <sys/socket.h>
79 #include <sys/socketvar.h>
80 #include <sys/signalvar.h>
81 #include <sys/un.h>
82 #include <sys/ktrace.h>
83 #include <sys/event.h>
84 #include <sys/atomic.h>
85 #include <sys/kauth.h>
86
87 #include <sys/mount.h>
88 #include <sys/syscallargs.h>
89
90 /*
91 * System call interface to the socket abstraction.
92 */
93 extern const struct fileops socketops;
94
95 static int sockargs_sb(struct sockaddr_big *, const void *, socklen_t);
96
97 int
98 sys___socket30(struct lwp *l, const struct sys___socket30_args *uap,
99 register_t *retval)
100 {
101 /* {
102 syscallarg(int) domain;
103 syscallarg(int) type;
104 syscallarg(int) protocol;
105 } */
106 int fd, error;
107
108 error = fsocreate(SCARG(uap, domain), NULL, SCARG(uap, type),
109 SCARG(uap, protocol), &fd);
110 if (error == 0) {
111 *retval = fd;
112 }
113 return error;
114 }
115
116 int
117 sys_bind(struct lwp *l, const struct sys_bind_args *uap, register_t *retval)
118 {
119 /* {
120 syscallarg(int) s;
121 syscallarg(const struct sockaddr *) name;
122 syscallarg(unsigned int) namelen;
123 } */
124 int error;
125 struct sockaddr_big sb;
126
127 error = sockargs_sb(&sb, SCARG(uap, name), SCARG(uap, namelen));
128 if (error)
129 return error;
130
131 return do_sys_bind(l, SCARG(uap, s), (struct sockaddr *)&sb);
132 }
133
134 int
135 do_sys_bind(struct lwp *l, int fd, struct sockaddr *nam)
136 {
137 struct socket *so;
138 int error;
139
140 if ((error = fd_getsock(fd, &so)) != 0)
141 return error;
142 error = sobind(so, nam, l);
143 fd_putfile(fd);
144 return error;
145 }
146
147 int
148 sys_listen(struct lwp *l, const struct sys_listen_args *uap, register_t *retval)
149 {
150 /* {
151 syscallarg(int) s;
152 syscallarg(int) backlog;
153 } */
154 struct socket *so;
155 int error;
156
157 if ((error = fd_getsock(SCARG(uap, s), &so)) != 0)
158 return (error);
159 error = solisten(so, SCARG(uap, backlog), l);
160 fd_putfile(SCARG(uap, s));
161 return error;
162 }
163
164 int
165 do_sys_accept(struct lwp *l, int sock, struct sockaddr *name,
166 register_t *new_sock, const sigset_t *mask, int flags, int clrflags)
167 {
168 file_t *fp, *fp2;
169 int error, fd;
170 struct socket *so, *so2;
171 short wakeup_state = 0;
172
173 if ((fp = fd_getfile(sock)) == NULL)
174 return EBADF;
175 if (fp->f_type != DTYPE_SOCKET) {
176 fd_putfile(sock);
177 return ENOTSOCK;
178 }
179 if ((error = fd_allocfile(&fp2, &fd)) != 0) {
180 fd_putfile(sock);
181 return error;
182 }
183 *new_sock = fd;
184 so = fp->f_socket;
185 solock(so);
186
187 if (__predict_false(mask))
188 sigsuspendsetup(l, mask);
189
190 if (!(so->so_proto->pr_flags & PR_LISTEN)) {
191 error = EOPNOTSUPP;
192 goto bad;
193 }
194 if ((so->so_options & SO_ACCEPTCONN) == 0) {
195 error = EINVAL;
196 goto bad;
197 }
198 if ((so->so_state & SS_NBIO) && so->so_qlen == 0) {
199 error = EWOULDBLOCK;
200 goto bad;
201 }
202 while (so->so_qlen == 0 && so->so_error == 0) {
203 if (so->so_state & SS_CANTRCVMORE) {
204 so->so_error = ECONNABORTED;
205 break;
206 }
207 if (wakeup_state & SS_RESTARTSYS) {
208 error = ERESTART;
209 goto bad;
210 }
211 error = sowait(so, true, 0);
212 if (error) {
213 goto bad;
214 }
215 wakeup_state = so->so_state;
216 }
217 if (so->so_error) {
218 error = so->so_error;
219 so->so_error = 0;
220 goto bad;
221 }
222 /* connection has been removed from the listen queue */
223 KNOTE(&so->so_rcv.sb_sel.sel_klist, NOTE_SUBMIT);
224 so2 = TAILQ_FIRST(&so->so_q);
225 if (soqremque(so2, 1) == 0)
226 panic("accept");
227 fp2->f_type = DTYPE_SOCKET;
228 fp2->f_flag = (fp->f_flag & ~clrflags) |
229 ((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0)|
230 ((flags & SOCK_NOSIGPIPE) ? FNOSIGPIPE : 0);
231 fp2->f_ops = &socketops;
232 fp2->f_socket = so2;
233 if (fp2->f_flag & FNONBLOCK)
234 so2->so_state |= SS_NBIO;
235 else
236 so2->so_state &= ~SS_NBIO;
237 error = soaccept(so2, name);
238 so2->so_cred = kauth_cred_dup(so->so_cred);
239 sounlock(so);
240 if (error) {
241 /* an error occurred, free the file descriptor and mbuf */
242 mutex_enter(&fp2->f_lock);
243 fp2->f_count++;
244 mutex_exit(&fp2->f_lock);
245 closef(fp2);
246 fd_abort(curproc, NULL, fd);
247 } else {
248 fd_set_exclose(l, fd, (flags & SOCK_CLOEXEC) != 0);
249 fd_affix(curproc, fp2, fd);
250 }
251 fd_putfile(sock);
252 if (__predict_false(mask))
253 sigsuspendteardown(l);
254 return error;
255 bad:
256 sounlock(so);
257 fd_putfile(sock);
258 fd_abort(curproc, fp2, fd);
259 if (__predict_false(mask))
260 sigsuspendteardown(l);
261 return error;
262 }
263
264 int
265 sys_accept(struct lwp *l, const struct sys_accept_args *uap, register_t *retval)
266 {
267 /* {
268 syscallarg(int) s;
269 syscallarg(struct sockaddr *) name;
270 syscallarg(unsigned int *) anamelen;
271 } */
272 int error, fd;
273 struct sockaddr_big name;
274
275 name.sb_len = UCHAR_MAX;
276 error = do_sys_accept(l, SCARG(uap, s), (struct sockaddr *)&name,
277 retval, NULL, 0, 0);
278 if (error != 0)
279 return error;
280 error = copyout_sockname_sb(SCARG(uap, name), SCARG(uap, anamelen),
281 MSG_LENUSRSPACE, &name);
282 if (error != 0) {
283 fd = (int)*retval;
284 if (fd_getfile(fd) != NULL)
285 (void)fd_close(fd);
286 }
287 return error;
288 }
289
290 int
291 sys_paccept(struct lwp *l, const struct sys_paccept_args *uap,
292 register_t *retval)
293 {
294 /* {
295 syscallarg(int) s;
296 syscallarg(struct sockaddr *) name;
297 syscallarg(unsigned int *) anamelen;
298 syscallarg(const sigset_t *) mask;
299 syscallarg(int) flags;
300 } */
301 int error, fd;
302 struct sockaddr_big name;
303 sigset_t *mask, amask;
304
305 if (SCARG(uap, mask) != NULL) {
306 error = copyin(SCARG(uap, mask), &amask, sizeof(amask));
307 if (error)
308 return error;
309 mask = &amask;
310 } else
311 mask = NULL;
312
313 name.sb_len = UCHAR_MAX;
314 error = do_sys_accept(l, SCARG(uap, s), (struct sockaddr *)&name,
315 retval, mask, SCARG(uap, flags), FNONBLOCK);
316 if (error != 0)
317 return error;
318 error = copyout_sockname_sb(SCARG(uap, name), SCARG(uap, anamelen),
319 MSG_LENUSRSPACE, &name);
320 if (error != 0) {
321 fd = (int)*retval;
322 if (fd_getfile(fd) != NULL)
323 (void)fd_close(fd);
324 }
325 return error;
326 }
327
328 int
329 sys_connect(struct lwp *l, const struct sys_connect_args *uap,
330 register_t *retval)
331 {
332 /* {
333 syscallarg(int) s;
334 syscallarg(const struct sockaddr *) name;
335 syscallarg(unsigned int) namelen;
336 } */
337 int error;
338 struct sockaddr_big sbig;
339
340 error = sockargs_sb(&sbig, SCARG(uap, name), SCARG(uap, namelen));
341 if (error)
342 return error;
343 return do_sys_connect(l, SCARG(uap, s), (struct sockaddr *)&sbig);
344 }
345
346 int
347 do_sys_connect(struct lwp *l, int fd, struct sockaddr *nam)
348 {
349 struct socket *so;
350 int error;
351 int interrupted = 0;
352
353 if ((error = fd_getsock(fd, &so)) != 0) {
354 return (error);
355 }
356 solock(so);
357 if ((so->so_state & SS_ISCONNECTING) != 0) {
358 error = EALREADY;
359 goto out;
360 }
361
362 error = soconnect(so, nam, l);
363 if (error)
364 goto bad;
365 if ((so->so_state & (SS_NBIO|SS_ISCONNECTING)) ==
366 (SS_NBIO|SS_ISCONNECTING)) {
367 error = EINPROGRESS;
368 goto out;
369 }
370 while ((so->so_state & SS_ISCONNECTING) != 0 && so->so_error == 0) {
371 error = sowait(so, true, 0);
372 if (__predict_false((so->so_state & SS_ISABORTING) != 0)) {
373 error = EPIPE;
374 interrupted = 1;
375 break;
376 }
377 if (error) {
378 if (error == EINTR || error == ERESTART)
379 interrupted = 1;
380 break;
381 }
382 }
383 if (error == 0) {
384 error = so->so_error;
385 so->so_error = 0;
386 }
387 bad:
388 if (!interrupted)
389 so->so_state &= ~SS_ISCONNECTING;
390 if (error == ERESTART)
391 error = EINTR;
392 out:
393 sounlock(so);
394 fd_putfile(fd);
395 return error;
396 }
397
398 static int
399 makesocket(struct lwp *l, file_t **fp, int *fd, int flags, int type,
400 int domain, int proto, struct socket *soo)
401 {
402 struct socket *so;
403 int error;
404
405 if ((error = socreate(domain, &so, type, proto, l, soo)) != 0) {
406 return error;
407 }
408 if (flags & SOCK_NONBLOCK) {
409 so->so_state |= SS_NBIO;
410 }
411
412 if ((error = fd_allocfile(fp, fd)) != 0) {
413 soclose(so);
414 return error;
415 }
416 fd_set_exclose(l, *fd, (flags & SOCK_CLOEXEC) != 0);
417 (*fp)->f_flag = FREAD|FWRITE|
418 ((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0)|
419 ((flags & SOCK_NOSIGPIPE) ? FNOSIGPIPE : 0);
420 (*fp)->f_type = DTYPE_SOCKET;
421 (*fp)->f_ops = &socketops;
422 (*fp)->f_socket = so;
423 return 0;
424 }
425
426 int
427 sys_socketpair(struct lwp *l, const struct sys_socketpair_args *uap,
428 register_t *retval)
429 {
430 /* {
431 syscallarg(int) domain;
432 syscallarg(int) type;
433 syscallarg(int) protocol;
434 syscallarg(int *) rsv;
435 } */
436 file_t *fp1, *fp2;
437 struct socket *so1, *so2;
438 int fd, error, sv[2];
439 proc_t *p = curproc;
440 int flags = SCARG(uap, type) & SOCK_FLAGS_MASK;
441 int type = SCARG(uap, type) & ~SOCK_FLAGS_MASK;
442 int domain = SCARG(uap, domain);
443 int proto = SCARG(uap, protocol);
444
445 error = makesocket(l, &fp1, &fd, flags, type, domain, proto, NULL);
446 if (error)
447 return error;
448 so1 = fp1->f_socket;
449 sv[0] = fd;
450
451 error = makesocket(l, &fp2, &fd, flags, type, domain, proto, so1);
452 if (error)
453 goto out;
454 so2 = fp2->f_socket;
455 sv[1] = fd;
456
457 solock(so1);
458 error = soconnect2(so1, so2);
459 if (error == 0 && type == SOCK_DGRAM) {
460 /*
461 * Datagram socket connection is asymmetric.
462 */
463 error = soconnect2(so2, so1);
464 }
465 sounlock(so1);
466
467 if (error == 0)
468 error = copyout(sv, SCARG(uap, rsv), sizeof(sv));
469 if (error == 0) {
470 fd_affix(p, fp2, sv[1]);
471 fd_affix(p, fp1, sv[0]);
472 return 0;
473 }
474 fd_abort(p, fp2, sv[1]);
475 (void)soclose(so2);
476 out:
477 fd_abort(p, fp1, sv[0]);
478 (void)soclose(so1);
479 return error;
480 }
481
482 int
483 sys_sendto(struct lwp *l, const struct sys_sendto_args *uap,
484 register_t *retval)
485 {
486 /* {
487 syscallarg(int) s;
488 syscallarg(const void *) buf;
489 syscallarg(size_t) len;
490 syscallarg(int) flags;
491 syscallarg(const struct sockaddr *) to;
492 syscallarg(unsigned int) tolen;
493 } */
494 struct msghdr msg;
495 struct iovec aiov;
496
497 msg.msg_name = __UNCONST(SCARG(uap, to)); /* XXXUNCONST kills const */
498 msg.msg_namelen = SCARG(uap, tolen);
499 msg.msg_iov = &aiov;
500 msg.msg_iovlen = 1;
501 msg.msg_control = NULL;
502 msg.msg_flags = 0;
503 aiov.iov_base = __UNCONST(SCARG(uap, buf)); /* XXXUNCONST kills const */
504 aiov.iov_len = SCARG(uap, len);
505 return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags),
506 retval);
507 }
508
509 int
510 sys_sendmsg(struct lwp *l, const struct sys_sendmsg_args *uap,
511 register_t *retval)
512 {
513 /* {
514 syscallarg(int) s;
515 syscallarg(const struct msghdr *) msg;
516 syscallarg(int) flags;
517 } */
518 struct msghdr msg;
519 int error;
520
521 error = copyin(SCARG(uap, msg), &msg, sizeof(msg));
522 if (error)
523 return (error);
524
525 msg.msg_flags = MSG_IOVUSRSPACE;
526 return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags),
527 retval);
528 }
529
530 int
531 do_sys_sendmsg_so(struct lwp *l, int s, struct socket *so, file_t *fp,
532 struct msghdr *mp, int flags, register_t *retsize)
533 {
534
535 struct iovec aiov[UIO_SMALLIOV], *iov = aiov, *tiov, *ktriov = NULL;
536 struct sockaddr *sa = NULL;
537 struct mbuf *to, *control;
538 struct uio auio;
539 size_t len, iovsz;
540 int i, error;
541
542 ktrkuser("msghdr", mp, sizeof(*mp));
543
544 /* If the caller passed us stuff in mbufs, we must free them. */
545 to = (mp->msg_flags & MSG_NAMEMBUF) ? mp->msg_name : NULL;
546 control = (mp->msg_flags & MSG_CONTROLMBUF) ? mp->msg_control : NULL;
547 iovsz = mp->msg_iovlen * sizeof(struct iovec);
548
549 if (mp->msg_flags & MSG_IOVUSRSPACE) {
550 if ((unsigned int)mp->msg_iovlen > UIO_SMALLIOV) {
551 if ((unsigned int)mp->msg_iovlen > IOV_MAX) {
552 error = EMSGSIZE;
553 goto bad;
554 }
555 iov = kmem_alloc(iovsz, KM_SLEEP);
556 }
557 if (mp->msg_iovlen != 0) {
558 error = copyin(mp->msg_iov, iov, iovsz);
559 if (error)
560 goto bad;
561 }
562 auio.uio_iov = iov;
563 } else
564 auio.uio_iov = mp->msg_iov;
565
566 auio.uio_iovcnt = mp->msg_iovlen;
567 auio.uio_rw = UIO_WRITE;
568 auio.uio_offset = 0; /* XXX */
569 auio.uio_resid = 0;
570 KASSERT(l == curlwp);
571 auio.uio_vmspace = l->l_proc->p_vmspace;
572
573 tiov = auio.uio_iov;
574 for (i = 0; i < auio.uio_iovcnt; i++, tiov++) {
575 /*
576 * Writes return ssize_t because -1 is returned on error.
577 * Therefore, we must restrict the length to SSIZE_MAX to
578 * avoid garbage return values.
579 */
580 auio.uio_resid += tiov->iov_len;
581 if (tiov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
582 error = EINVAL;
583 goto bad;
584 }
585 }
586
587 if (mp->msg_name && to == NULL) {
588 error = sockargs(&to, mp->msg_name, mp->msg_namelen,
589 UIO_USERSPACE, MT_SONAME);
590 if (error)
591 goto bad;
592 }
593
594 if (mp->msg_control) {
595 if (mp->msg_controllen < CMSG_ALIGN(sizeof(struct cmsghdr))) {
596 error = EINVAL;
597 goto bad;
598 }
599 if (control == NULL) {
600 error = sockargs(&control, mp->msg_control,
601 mp->msg_controllen, UIO_USERSPACE, MT_CONTROL);
602 if (error)
603 goto bad;
604 }
605 }
606
607 if (ktrpoint(KTR_GENIO) && iovsz > 0) {
608 ktriov = kmem_alloc(iovsz, KM_SLEEP);
609 memcpy(ktriov, auio.uio_iov, iovsz);
610 }
611
612 if (mp->msg_name)
613 MCLAIM(to, so->so_mowner);
614 if (mp->msg_control)
615 MCLAIM(control, so->so_mowner);
616
617 if (to) {
618 sa = mtod(to, struct sockaddr *);
619 }
620
621 len = auio.uio_resid;
622 error = (*so->so_send)(so, sa, &auio, NULL, control, flags, l);
623 /* Protocol is responsible for freeing 'control' */
624 control = NULL;
625
626 if (error) {
627 if (auio.uio_resid != len && (error == ERESTART ||
628 error == EINTR || error == EWOULDBLOCK))
629 error = 0;
630 if (error == EPIPE && (fp->f_flag & FNOSIGPIPE) == 0 &&
631 (flags & MSG_NOSIGNAL) == 0) {
632 mutex_enter(proc_lock);
633 psignal(l->l_proc, SIGPIPE);
634 mutex_exit(proc_lock);
635 }
636 }
637 if (error == 0)
638 *retsize = len - auio.uio_resid;
639
640 bad:
641 if (ktriov != NULL) {
642 ktrgeniov(s, UIO_WRITE, ktriov, *retsize, error);
643 kmem_free(ktriov, iovsz);
644 }
645
646 if (iov != aiov)
647 kmem_free(iov, iovsz);
648 if (to)
649 m_freem(to);
650 if (control)
651 m_freem(control);
652
653 return error;
654 }
655
656 int
657 do_sys_sendmsg(struct lwp *l, int s, struct msghdr *mp, int flags,
658 register_t *retsize)
659 {
660 int error;
661 struct socket *so;
662 file_t *fp;
663
664 if ((error = fd_getsock1(s, &so, &fp)) != 0) {
665 /* We have to free msg_name and msg_control ourselves */
666 if (mp->msg_flags & MSG_NAMEMBUF)
667 m_freem(mp->msg_name);
668 if (mp->msg_flags & MSG_CONTROLMBUF)
669 m_freem(mp->msg_control);
670 return error;
671 }
672 error = do_sys_sendmsg_so(l, s, so, fp, mp, flags, retsize);
673 /* msg_name and msg_control freed */
674 fd_putfile(s);
675 return error;
676 }
677
678 int
679 sys_recvfrom(struct lwp *l, const struct sys_recvfrom_args *uap,
680 register_t *retval)
681 {
682 /* {
683 syscallarg(int) s;
684 syscallarg(void *) buf;
685 syscallarg(size_t) len;
686 syscallarg(int) flags;
687 syscallarg(struct sockaddr *) from;
688 syscallarg(unsigned int *) fromlenaddr;
689 } */
690 struct msghdr msg;
691 struct iovec aiov;
692 int error;
693 struct mbuf *from;
694
695 msg.msg_name = NULL;
696 msg.msg_iov = &aiov;
697 msg.msg_iovlen = 1;
698 aiov.iov_base = SCARG(uap, buf);
699 aiov.iov_len = SCARG(uap, len);
700 msg.msg_control = NULL;
701 msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
702
703 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, NULL, retval);
704 if (error != 0)
705 return error;
706
707 error = copyout_sockname(SCARG(uap, from), SCARG(uap, fromlenaddr),
708 MSG_LENUSRSPACE, from);
709 if (from != NULL)
710 m_free(from);
711 return error;
712 }
713
714 int
715 sys_recvmsg(struct lwp *l, const struct sys_recvmsg_args *uap,
716 register_t *retval)
717 {
718 /* {
719 syscallarg(int) s;
720 syscallarg(struct msghdr *) msg;
721 syscallarg(int) flags;
722 } */
723 struct msghdr msg;
724 int error;
725 struct mbuf *from, *control;
726
727 error = copyin(SCARG(uap, msg), &msg, sizeof(msg));
728 if (error)
729 return error;
730
731 msg.msg_flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE;
732
733 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
734 msg.msg_control != NULL ? &control : NULL, retval);
735 if (error != 0)
736 return error;
737
738 if (msg.msg_control != NULL)
739 error = copyout_msg_control(l, &msg, control);
740
741 if (error == 0)
742 error = copyout_sockname(msg.msg_name, &msg.msg_namelen, 0,
743 from);
744 if (from != NULL)
745 m_free(from);
746 if (error == 0) {
747 ktrkuser("msghdr", &msg, sizeof(msg));
748 error = copyout(&msg, SCARG(uap, msg), sizeof(msg));
749 }
750
751 return error;
752 }
753
754 int
755 sys_sendmmsg(struct lwp *l, const struct sys_sendmmsg_args *uap,
756 register_t *retval)
757 {
758 /* {
759 syscallarg(int) s;
760 syscallarg(struct mmsghdr *) mmsg;
761 syscallarg(unsigned int) vlen;
762 syscallarg(unsigned int) flags;
763 } */
764 struct mmsghdr mmsg;
765 struct socket *so;
766 file_t *fp;
767 struct msghdr *msg = &mmsg.msg_hdr;
768 int error, s;
769 unsigned int vlen, flags, dg;
770
771 s = SCARG(uap, s);
772 if ((error = fd_getsock1(s, &so, &fp)) != 0)
773 return error;
774
775 vlen = SCARG(uap, vlen);
776 if (vlen > 1024)
777 vlen = 1024;
778
779 flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE;
780
781 for (dg = 0; dg < vlen;) {
782 error = copyin(SCARG(uap, mmsg) + dg, &mmsg, sizeof(mmsg));
783 if (error)
784 break;
785
786 msg->msg_flags = flags;
787
788 error = do_sys_sendmsg_so(l, s, so, fp, msg, flags, retval);
789 if (error)
790 break;
791
792 ktrkuser("msghdr", msg, sizeof(*msg));
793 mmsg.msg_len = *retval;
794 error = copyout(&mmsg, SCARG(uap, mmsg) + dg, sizeof(mmsg));
795 if (error)
796 break;
797 dg++;
798
799 }
800
801 *retval = dg;
802 if (error)
803 so->so_error = error;
804
805 fd_putfile(s);
806
807 /*
808 * If we succeeded at least once, return 0, hopefully so->so_error
809 * will catch it next time.
810 */
811 if (dg)
812 return 0;
813 return error;
814 }
815
816 /*
817 * Adjust for a truncated SCM_RIGHTS control message.
818 * This means closing any file descriptors that aren't present
819 * in the returned buffer.
820 * m is the mbuf holding the (already externalized) SCM_RIGHTS message.
821 */
822 static void
823 free_rights(struct mbuf *m)
824 {
825 struct cmsghdr *cm;
826 int *fdv;
827 unsigned int nfds, i;
828
829 KASSERT(sizeof(*cm) <= m->m_len);
830 cm = mtod(m, struct cmsghdr *);
831
832 KASSERT(CMSG_ALIGN(sizeof(*cm)) <= cm->cmsg_len);
833 KASSERT(cm->cmsg_len <= m->m_len);
834 nfds = (cm->cmsg_len - CMSG_ALIGN(sizeof(*cm))) / sizeof(int);
835 fdv = (int *)CMSG_DATA(cm);
836
837 for (i = 0; i < nfds; i++)
838 if (fd_getfile(fdv[i]) != NULL)
839 (void)fd_close(fdv[i]);
840 }
841
842 void
843 free_control_mbuf(struct lwp *l, struct mbuf *control, struct mbuf *uncopied)
844 {
845 struct mbuf *next;
846 struct cmsghdr *cmsg;
847 bool do_free_rights = false;
848
849 while (control != NULL) {
850 cmsg = mtod(control, struct cmsghdr *);
851 if (control == uncopied)
852 do_free_rights = true;
853 if (do_free_rights && cmsg->cmsg_level == SOL_SOCKET
854 && cmsg->cmsg_type == SCM_RIGHTS)
855 free_rights(control);
856 next = control->m_next;
857 m_free(control);
858 control = next;
859 }
860 }
861
862 /* Copy socket control/CMSG data to user buffer, frees the mbuf */
863 int
864 copyout_msg_control(struct lwp *l, struct msghdr *mp, struct mbuf *control)
865 {
866 int i, len, error = 0;
867 struct cmsghdr *cmsg;
868 struct mbuf *m;
869 char *q;
870
871 len = mp->msg_controllen;
872 if (len <= 0 || control == 0) {
873 mp->msg_controllen = 0;
874 free_control_mbuf(l, control, control);
875 return 0;
876 }
877
878 q = (char *)mp->msg_control;
879
880 for (m = control; m != NULL; ) {
881 cmsg = mtod(m, struct cmsghdr *);
882 i = m->m_len;
883 if (len < i) {
884 mp->msg_flags |= MSG_CTRUNC;
885 if (cmsg->cmsg_level == SOL_SOCKET
886 && cmsg->cmsg_type == SCM_RIGHTS)
887 /* Do not truncate me ... */
888 break;
889 i = len;
890 }
891 error = copyout(mtod(m, void *), q, i);
892 ktrkuser(mbuftypes[MT_CONTROL], cmsg, cmsg->cmsg_len);
893 if (error != 0) {
894 /* We must free all the SCM_RIGHTS */
895 m = control;
896 break;
897 }
898 m = m->m_next;
899 if (m)
900 i = ALIGN(i);
901 q += i;
902 len -= i;
903 if (len <= 0)
904 break;
905 }
906
907 free_control_mbuf(l, control, m);
908
909 mp->msg_controllen = q - (char *)mp->msg_control;
910 return error;
911 }
912
913 int
914 do_sys_recvmsg_so(struct lwp *l, int s, struct socket *so, struct msghdr *mp,
915 struct mbuf **from, struct mbuf **control, register_t *retsize)
916 {
917 struct iovec aiov[UIO_SMALLIOV], *iov = aiov, *tiov, *ktriov = NULL;
918 struct uio auio;
919 size_t len, iovsz;
920 int i, error;
921
922 ktrkuser("msghdr", mp, sizeof(*mp));
923
924 *from = NULL;
925 if (control != NULL)
926 *control = NULL;
927
928 iovsz = mp->msg_iovlen * sizeof(struct iovec);
929
930 if (mp->msg_flags & MSG_IOVUSRSPACE) {
931 if ((unsigned int)mp->msg_iovlen > UIO_SMALLIOV) {
932 if ((unsigned int)mp->msg_iovlen > IOV_MAX) {
933 error = EMSGSIZE;
934 goto out;
935 }
936 iov = kmem_alloc(iovsz, KM_SLEEP);
937 }
938 if (mp->msg_iovlen != 0) {
939 error = copyin(mp->msg_iov, iov, iovsz);
940 if (error)
941 goto out;
942 }
943 auio.uio_iov = iov;
944 } else
945 auio.uio_iov = mp->msg_iov;
946 auio.uio_iovcnt = mp->msg_iovlen;
947 auio.uio_rw = UIO_READ;
948 auio.uio_offset = 0; /* XXX */
949 auio.uio_resid = 0;
950 KASSERT(l == curlwp);
951 auio.uio_vmspace = l->l_proc->p_vmspace;
952
953 tiov = auio.uio_iov;
954 for (i = 0; i < auio.uio_iovcnt; i++, tiov++) {
955 /*
956 * Reads return ssize_t because -1 is returned on error.
957 * Therefore we must restrict the length to SSIZE_MAX to
958 * avoid garbage return values.
959 */
960 auio.uio_resid += tiov->iov_len;
961 if (tiov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
962 error = EINVAL;
963 goto out;
964 }
965 }
966
967 if (ktrpoint(KTR_GENIO) && iovsz > 0) {
968 ktriov = kmem_alloc(iovsz, KM_SLEEP);
969 memcpy(ktriov, auio.uio_iov, iovsz);
970 }
971
972 len = auio.uio_resid;
973 mp->msg_flags &= MSG_USERFLAGS;
974 error = (*so->so_receive)(so, from, &auio, NULL, control,
975 &mp->msg_flags);
976 KASSERT(*from == NULL || (*from)->m_next == NULL);
977 len -= auio.uio_resid;
978 *retsize = len;
979 if (error != 0 && len != 0
980 && (error == ERESTART || error == EINTR || error == EWOULDBLOCK))
981 /* Some data transferred */
982 error = 0;
983
984 if (ktriov != NULL) {
985 ktrgeniov(s, UIO_READ, ktriov, len, error);
986 kmem_free(ktriov, iovsz);
987 }
988
989 if (error != 0) {
990 m_freem(*from);
991 *from = NULL;
992 if (control != NULL) {
993 free_control_mbuf(l, *control, *control);
994 *control = NULL;
995 }
996 }
997 out:
998 if (iov != aiov)
999 kmem_free(iov, iovsz);
1000 return error;
1001 }
1002
1003
1004 int
1005 do_sys_recvmsg(struct lwp *l, int s, struct msghdr *mp,
1006 struct mbuf **from, struct mbuf **control, register_t *retsize)
1007 {
1008 int error;
1009 struct socket *so;
1010
1011 if ((error = fd_getsock(s, &so)) != 0)
1012 return error;
1013 error = do_sys_recvmsg_so(l, s, so, mp, from, control, retsize);
1014 fd_putfile(s);
1015 return error;
1016 }
1017
1018 int
1019 sys_recvmmsg(struct lwp *l, const struct sys_recvmmsg_args *uap,
1020 register_t *retval)
1021 {
1022 /* {
1023 syscallarg(int) s;
1024 syscallarg(struct mmsghdr *) mmsg;
1025 syscallarg(unsigned int) vlen;
1026 syscallarg(unsigned int) flags;
1027 syscallarg(struct timespec *) timeout;
1028 } */
1029 struct mmsghdr mmsg;
1030 struct socket *so;
1031 struct msghdr *msg = &mmsg.msg_hdr;
1032 int error, s;
1033 struct mbuf *from, *control;
1034 struct timespec ts, now;
1035 unsigned int vlen, flags, dg;
1036
1037 if (SCARG(uap, timeout)) {
1038 if ((error = copyin(SCARG(uap, timeout), &ts, sizeof(ts))) != 0)
1039 return error;
1040 getnanotime(&now);
1041 timespecadd(&now, &ts, &ts);
1042 }
1043
1044 s = SCARG(uap, s);
1045 if ((error = fd_getsock(s, &so)) != 0)
1046 return error;
1047
1048 vlen = SCARG(uap, vlen);
1049 if (vlen > 1024)
1050 vlen = 1024;
1051
1052 from = NULL;
1053 flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE;
1054
1055 for (dg = 0; dg < vlen;) {
1056 error = copyin(SCARG(uap, mmsg) + dg, &mmsg, sizeof(mmsg));
1057 if (error)
1058 break;
1059
1060 msg->msg_flags = flags & ~MSG_WAITFORONE;
1061
1062 if (from != NULL) {
1063 m_free(from);
1064 from = NULL;
1065 }
1066
1067 error = do_sys_recvmsg_so(l, s, so, msg, &from,
1068 msg->msg_control != NULL ? &control : NULL, retval);
1069 if (error) {
1070 if (error == EAGAIN && dg > 0)
1071 error = 0;
1072 break;
1073 }
1074
1075 if (msg->msg_control != NULL)
1076 error = copyout_msg_control(l, msg, control);
1077 if (error)
1078 break;
1079
1080 error = copyout_sockname(msg->msg_name, &msg->msg_namelen, 0,
1081 from);
1082 if (error)
1083 break;
1084
1085 ktrkuser("msghdr", msg, sizeof *msg);
1086 mmsg.msg_len = *retval;
1087
1088 error = copyout(&mmsg, SCARG(uap, mmsg) + dg, sizeof(mmsg));
1089 if (error)
1090 break;
1091
1092 dg++;
1093 if (msg->msg_flags & MSG_OOB)
1094 break;
1095
1096 if (SCARG(uap, timeout)) {
1097 getnanotime(&now);
1098 timespecsub(&now, &ts, &now);
1099 if (now.tv_sec > 0)
1100 break;
1101 }
1102
1103 if (flags & MSG_WAITFORONE)
1104 flags |= MSG_DONTWAIT;
1105
1106 }
1107
1108 if (from != NULL)
1109 m_free(from);
1110
1111 *retval = dg;
1112 if (error)
1113 so->so_error = error;
1114
1115 fd_putfile(s);
1116
1117 /*
1118 * If we succeeded at least once, return 0, hopefully so->so_error
1119 * will catch it next time.
1120 */
1121 if (dg)
1122 return 0;
1123
1124 return error;
1125 }
1126
1127 int
1128 sys_shutdown(struct lwp *l, const struct sys_shutdown_args *uap,
1129 register_t *retval)
1130 {
1131 /* {
1132 syscallarg(int) s;
1133 syscallarg(int) how;
1134 } */
1135 struct socket *so;
1136 int error;
1137
1138 if ((error = fd_getsock(SCARG(uap, s), &so)) != 0)
1139 return error;
1140 solock(so);
1141 error = soshutdown(so, SCARG(uap, how));
1142 sounlock(so);
1143 fd_putfile(SCARG(uap, s));
1144 return error;
1145 }
1146
1147 int
1148 sys_setsockopt(struct lwp *l, const struct sys_setsockopt_args *uap,
1149 register_t *retval)
1150 {
1151 /* {
1152 syscallarg(int) s;
1153 syscallarg(int) level;
1154 syscallarg(int) name;
1155 syscallarg(const void *) val;
1156 syscallarg(unsigned int) valsize;
1157 } */
1158 struct sockopt sopt;
1159 struct socket *so;
1160 file_t *fp;
1161 int error;
1162 unsigned int len;
1163
1164 len = SCARG(uap, valsize);
1165 if (len > 0 && SCARG(uap, val) == NULL)
1166 return EINVAL;
1167
1168 if (len > MCLBYTES)
1169 return EINVAL;
1170
1171 if ((error = fd_getsock1(SCARG(uap, s), &so, &fp)) != 0)
1172 return (error);
1173
1174 sockopt_init(&sopt, SCARG(uap, level), SCARG(uap, name), len);
1175
1176 if (len > 0) {
1177 error = copyin(SCARG(uap, val), sopt.sopt_data, len);
1178 if (error)
1179 goto out;
1180 }
1181
1182 error = sosetopt(so, &sopt);
1183 if (so->so_options & SO_NOSIGPIPE)
1184 atomic_or_uint(&fp->f_flag, FNOSIGPIPE);
1185 else
1186 atomic_and_uint(&fp->f_flag, ~FNOSIGPIPE);
1187
1188 out:
1189 sockopt_destroy(&sopt);
1190 fd_putfile(SCARG(uap, s));
1191 return error;
1192 }
1193
1194 int
1195 sys_getsockopt(struct lwp *l, const struct sys_getsockopt_args *uap,
1196 register_t *retval)
1197 {
1198 /* {
1199 syscallarg(int) s;
1200 syscallarg(int) level;
1201 syscallarg(int) name;
1202 syscallarg(void *) val;
1203 syscallarg(unsigned int *) avalsize;
1204 } */
1205 struct sockopt sopt;
1206 struct socket *so;
1207 file_t *fp;
1208 unsigned int valsize, len;
1209 int error;
1210
1211 if (SCARG(uap, val) != NULL) {
1212 error = copyin(SCARG(uap, avalsize), &valsize, sizeof(valsize));
1213 if (error)
1214 return error;
1215 } else
1216 valsize = 0;
1217
1218 if ((error = fd_getsock1(SCARG(uap, s), &so, &fp)) != 0)
1219 return (error);
1220
1221 if (valsize > MCLBYTES)
1222 return EINVAL;
1223
1224 sockopt_init(&sopt, SCARG(uap, level), SCARG(uap, name), valsize);
1225
1226 if (fp->f_flag & FNOSIGPIPE)
1227 so->so_options |= SO_NOSIGPIPE;
1228 else
1229 so->so_options &= ~SO_NOSIGPIPE;
1230 error = sogetopt(so, &sopt);
1231 if (error)
1232 goto out;
1233
1234 if (valsize > 0) {
1235 len = min(valsize, sopt.sopt_retsize);
1236 error = copyout(sopt.sopt_data, SCARG(uap, val), len);
1237 if (error)
1238 goto out;
1239
1240 error = copyout(&len, SCARG(uap, avalsize), sizeof(len));
1241 if (error)
1242 goto out;
1243 }
1244
1245 out:
1246 sockopt_destroy(&sopt);
1247 fd_putfile(SCARG(uap, s));
1248 return error;
1249 }
1250
1251 #ifdef PIPE_SOCKETPAIR
1252
1253 int
1254 pipe1(struct lwp *l, int *fildes, int flags)
1255 {
1256 file_t *rf, *wf;
1257 struct socket *rso, *wso;
1258 int fd, error;
1259 proc_t *p;
1260
1261 if (flags & ~(O_CLOEXEC|O_NONBLOCK|O_NOSIGPIPE))
1262 return EINVAL;
1263 p = curproc;
1264 if ((error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, l, NULL)) != 0)
1265 return error;
1266 if ((error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, l, rso)) != 0)
1267 goto free1;
1268 /* remember this socket pair implements a pipe */
1269 wso->so_state |= SS_ISAPIPE;
1270 rso->so_state |= SS_ISAPIPE;
1271 if ((error = fd_allocfile(&rf, &fd)) != 0)
1272 goto free2;
1273 fildes[0] = fd;
1274 rf->f_flag = FREAD | flags;
1275 rf->f_type = DTYPE_SOCKET;
1276 rf->f_ops = &socketops;
1277 rf->f_socket = rso;
1278 if ((error = fd_allocfile(&wf, &fd)) != 0)
1279 goto free3;
1280 wf->f_flag = FWRITE | flags;
1281 wf->f_type = DTYPE_SOCKET;
1282 wf->f_ops = &socketops;
1283 wf->f_socket = wso;
1284 fildes[1] = fd;
1285 solock(wso);
1286 error = unp_connect2(wso, rso);
1287 sounlock(wso);
1288 if (error != 0)
1289 goto free4;
1290 fd_affix(p, wf, fildes[1]);
1291 fd_affix(p, rf, fildes[0]);
1292 return (0);
1293 free4:
1294 fd_abort(p, wf, fildes[1]);
1295 free3:
1296 fd_abort(p, rf, fildes[0]);
1297 free2:
1298 (void)soclose(wso);
1299 free1:
1300 (void)soclose(rso);
1301 return error;
1302 }
1303 #endif /* PIPE_SOCKETPAIR */
1304
1305 /*
1306 * Get peer socket name.
1307 */
1308 int
1309 do_sys_getpeername(int fd, struct sockaddr *nam)
1310 {
1311 struct socket *so;
1312 int error;
1313
1314 if ((error = fd_getsock(fd, &so)) != 0)
1315 return error;
1316
1317 solock(so);
1318 if ((so->so_state & SS_ISCONNECTED) == 0)
1319 error = ENOTCONN;
1320 else {
1321 error = (*so->so_proto->pr_usrreqs->pr_peeraddr)(so, nam);
1322 }
1323 sounlock(so);
1324 fd_putfile(fd);
1325 return error;
1326 }
1327
1328 /*
1329 * Get local socket name.
1330 */
1331 int
1332 do_sys_getsockname(int fd, struct sockaddr *nam)
1333 {
1334 struct socket *so;
1335 int error;
1336
1337 if ((error = fd_getsock(fd, &so)) != 0)
1338 return error;
1339
1340 solock(so);
1341 error = (*so->so_proto->pr_usrreqs->pr_sockaddr)(so, nam);
1342 sounlock(so);
1343 fd_putfile(fd);
1344 return error;
1345 }
1346
1347 int
1348 copyout_sockname_sb(struct sockaddr *asa, unsigned int *alen, int flags,
1349 struct sockaddr_big *addr)
1350 {
1351 unsigned int len;
1352 int error;
1353
1354 if (asa == NULL)
1355 /* Assume application not interested */
1356 return 0;
1357
1358 if (flags & MSG_LENUSRSPACE) {
1359 error = copyin(alen, &len, sizeof(len));
1360 if (error)
1361 return error;
1362 } else
1363 len = *alen;
1364
1365 if (addr == NULL) {
1366 len = 0;
1367 error = 0;
1368 } else {
1369 if (len > addr->sb_len)
1370 len = addr->sb_len;
1371 /* XXX addr isn't an mbuf... */
1372 ktrkuser(mbuftypes[MT_SONAME], addr, len);
1373 error = copyout(addr, asa, len);
1374 }
1375
1376 if (error == 0) {
1377 if (flags & MSG_LENUSRSPACE)
1378 error = copyout(&len, alen, sizeof(len));
1379 else
1380 *alen = len;
1381 }
1382
1383 return error;
1384 }
1385
1386 int
1387 copyout_sockname(struct sockaddr *asa, unsigned int *alen, int flags,
1388 struct mbuf *addr)
1389 {
1390 int len;
1391 int error;
1392
1393 if (asa == NULL)
1394 /* Assume application not interested */
1395 return 0;
1396
1397 if (flags & MSG_LENUSRSPACE) {
1398 error = copyin(alen, &len, sizeof(len));
1399 if (error)
1400 return error;
1401 } else
1402 len = *alen;
1403 if (len < 0)
1404 return EINVAL;
1405
1406 if (addr == NULL) {
1407 len = 0;
1408 error = 0;
1409 } else {
1410 if (len > addr->m_len)
1411 len = addr->m_len;
1412 /* Maybe this ought to copy a chain ? */
1413 ktrkuser(mbuftypes[MT_SONAME], mtod(addr, void *), len);
1414 error = copyout(mtod(addr, void *), asa, len);
1415 }
1416
1417 if (error == 0) {
1418 if (flags & MSG_LENUSRSPACE)
1419 error = copyout(&len, alen, sizeof(len));
1420 else
1421 *alen = len;
1422 }
1423
1424 return error;
1425 }
1426
1427 /*
1428 * Get socket name.
1429 */
1430 int
1431 sys_getsockname(struct lwp *l, const struct sys_getsockname_args *uap,
1432 register_t *retval)
1433 {
1434 /* {
1435 syscallarg(int) fdes;
1436 syscallarg(struct sockaddr *) asa;
1437 syscallarg(unsigned int *) alen;
1438 } */
1439 struct sockaddr_big sbig;
1440 int error;
1441
1442 sbig.sb_len = UCHAR_MAX;
1443 error = do_sys_getsockname(SCARG(uap, fdes), (struct sockaddr *)&sbig);
1444 if (error != 0)
1445 return error;
1446
1447 error = copyout_sockname_sb(SCARG(uap, asa), SCARG(uap, alen),
1448 MSG_LENUSRSPACE, &sbig);
1449 return error;
1450 }
1451
1452 /*
1453 * Get name of peer for connected socket.
1454 */
1455 int
1456 sys_getpeername(struct lwp *l, const struct sys_getpeername_args *uap,
1457 register_t *retval)
1458 {
1459 /* {
1460 syscallarg(int) fdes;
1461 syscallarg(struct sockaddr *) asa;
1462 syscallarg(unsigned int *) alen;
1463 } */
1464 struct sockaddr_big sbig;
1465 int error;
1466
1467 sbig.sb_len = UCHAR_MAX;
1468 error = do_sys_getpeername(SCARG(uap, fdes), (struct sockaddr *)&sbig);
1469 if (error != 0)
1470 return error;
1471
1472 error = copyout_sockname_sb(SCARG(uap, asa), SCARG(uap, alen),
1473 MSG_LENUSRSPACE, &sbig);
1474 return error;
1475 }
1476
1477 static int
1478 sockargs_sb(struct sockaddr_big *sb, const void *name, socklen_t buflen)
1479 {
1480 int error;
1481
1482 /*
1483 * We can't allow socket names > UCHAR_MAX in length, since that
1484 * will overflow sb_len. Further no reasonable buflen is <=
1485 * offsetof(sockaddr_big, sb_data) since it shall be at least
1486 * the size of the preamble sb_len and sb_family members.
1487 */
1488 if (buflen > UCHAR_MAX ||
1489 buflen <= offsetof(struct sockaddr_big, sb_data))
1490 return EINVAL;
1491
1492 error = copyin(name, (void *)sb, buflen);
1493 if (error)
1494 return error;
1495
1496 ktrkuser(mbuftypes[MT_SONAME], sb, buflen);
1497 #if BYTE_ORDER != BIG_ENDIAN
1498 /*
1499 * 4.3BSD compat thing - need to stay, since bind(2),
1500 * connect(2), sendto(2) were not versioned for COMPAT_43.
1501 */
1502 if (sb->sb_family == 0 && sb->sb_len < AF_MAX)
1503 sb->sb_family = sb->sb_len;
1504 #endif
1505 sb->sb_len = buflen;
1506 return 0;
1507 }
1508
1509 /*
1510 * XXX In a perfect world, we wouldn't pass around socket control
1511 * XXX arguments in mbufs, and this could go away.
1512 */
1513 int
1514 sockargs(struct mbuf **mp, const void *bf, size_t buflen, enum uio_seg seg,
1515 int type)
1516 {
1517 struct mbuf *m;
1518 int error;
1519
1520 /*
1521 * We can't allow socket names > UCHAR_MAX in length, since that
1522 * will overflow sa_len. Control data more than a page size in
1523 * length is just too much.
1524 */
1525 if (buflen > (type == MT_SONAME ? UCHAR_MAX : PAGE_SIZE))
1526 return EINVAL;
1527
1528 /*
1529 * length must greater than sizeof(sa_family) + sizeof(sa_len)
1530 */
1531 if (type == MT_SONAME && buflen <= 2)
1532 return EINVAL;
1533
1534 /* Allocate an mbuf to hold the arguments. */
1535 m = m_get(M_WAIT, type);
1536 /* can't claim. don't who to assign it to. */
1537 if (buflen > MLEN) {
1538 /*
1539 * Won't fit into a regular mbuf, so we allocate just
1540 * enough external storage to hold the argument.
1541 */
1542 MEXTMALLOC(m, buflen, M_WAITOK);
1543 }
1544 m->m_len = buflen;
1545 if (seg == UIO_USERSPACE) {
1546 error = copyin(bf, mtod(m, void *), buflen);
1547 if (error) {
1548 (void)m_free(m);
1549 return error;
1550 }
1551 } else {
1552 memcpy(mtod(m, void *), bf, buflen);
1553 }
1554 *mp = m;
1555 switch (type) {
1556 case MT_SONAME:
1557 ktrkuser(mbuftypes[type], mtod(m, void *), buflen);
1558
1559 struct sockaddr *sa = mtod(m, struct sockaddr *);
1560 #if BYTE_ORDER != BIG_ENDIAN
1561 /*
1562 * 4.3BSD compat thing - need to stay, since bind(2),
1563 * connect(2), sendto(2) were not versioned for COMPAT_43.
1564 */
1565 if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
1566 sa->sa_family = sa->sa_len;
1567 #endif
1568 sa->sa_len = buflen;
1569 return 0;
1570 case MT_CONTROL:
1571 if (!KTRPOINT(curproc, KTR_USER))
1572 return 0;
1573
1574 struct msghdr mhdr;
1575 mhdr.msg_control = mtod(m, void *);
1576 mhdr.msg_controllen = buflen;
1577 for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mhdr); cmsg;
1578 cmsg = CMSG_NXTHDR(&mhdr, cmsg)) {
1579 ktrkuser(mbuftypes[type], cmsg, cmsg->cmsg_len);
1580 }
1581 return 0;
1582 default:
1583 return EINVAL;
1584 }
1585 }
1586