kern_sendfile.c (269807) | kern_sendfile.c (272823) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * sendfile(2) and related extensions: 6 * Copyright (c) 1998, David Greenman. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 19 unchanged lines hidden (view full) --- 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94 33 */ 34 35#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1982, 1986, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * sendfile(2) and related extensions: 6 * Copyright (c) 1998, David Greenman. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 19 unchanged lines hidden (view full) --- 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94 33 */ 34 35#include <sys/cdefs.h> |
36__FBSDID("$FreeBSD: head/sys/kern/uipc_syscalls.c 269807 2014-08-11 12:59:55Z glebius $"); | 36__FBSDID("$FreeBSD: head/sys/kern/uipc_syscalls.c 272823 2014-10-09 15:16:52Z marcel $"); |
37 38#include "opt_capsicum.h" 39#include "opt_inet.h" 40#include "opt_inet6.h" | 37 38#include "opt_capsicum.h" 39#include "opt_inet.h" 40#include "opt_inet6.h" |
41#include "opt_sctp.h" | |
42#include "opt_compat.h" 43#include "opt_ktrace.h" 44 45#include <sys/param.h> 46#include <sys/systm.h> 47#include <sys/capsicum.h> 48#include <sys/condvar.h> 49#include <sys/kernel.h> --- 40 unchanged lines hidden (view full) --- 90#include <vm/vm_param.h> 91#include <vm/vm_object.h> 92#include <vm/vm_page.h> 93#include <vm/vm_pager.h> 94#include <vm/vm_kern.h> 95#include <vm/vm_extern.h> 96#include <vm/uma.h> 97 | 41#include "opt_compat.h" 42#include "opt_ktrace.h" 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/capsicum.h> 47#include <sys/condvar.h> 48#include <sys/kernel.h> --- 40 unchanged lines hidden (view full) --- 89#include <vm/vm_param.h> 90#include <vm/vm_object.h> 91#include <vm/vm_page.h> 92#include <vm/vm_pager.h> 93#include <vm/vm_kern.h> 94#include <vm/vm_extern.h> 95#include <vm/uma.h> 96 |
98#if defined(INET) || defined(INET6) 99#ifdef SCTP 100#include <netinet/sctp.h> 101#include <netinet/sctp_peeloff.h> 102#endif /* SCTP */ 103#endif /* INET || INET6 */ 104 | |
105/* 106 * Flags for accept1() and kern_accept4(), in addition to SOCK_CLOEXEC 107 * and SOCK_NONBLOCK. 108 */ 109#define ACCEPT4_INHERIT 0x1 110#define ACCEPT4_COMPAT 0x2 111 112static int sendit(struct thread *td, int s, struct msghdr *mp, int flags); --- 80 unchanged lines hidden (view full) --- 193SYSCTL_PROC(_kern_ipc, OID_AUTO, sfstat, CTLTYPE_OPAQUE | CTLFLAG_RW, 194 NULL, 0, sfstat_sysctl, "I", "sendfile statistics"); 195 196/* 197 * Convert a user file descriptor to a kernel file entry and check if required 198 * capability rights are present. 199 * A reference on the file entry is held upon returning. 200 */ | 97/* 98 * Flags for accept1() and kern_accept4(), in addition to SOCK_CLOEXEC 99 * and SOCK_NONBLOCK. 100 */ 101#define ACCEPT4_INHERIT 0x1 102#define ACCEPT4_COMPAT 0x2 103 104static int sendit(struct thread *td, int s, struct msghdr *mp, int flags); --- 80 unchanged lines hidden (view full) --- 185SYSCTL_PROC(_kern_ipc, OID_AUTO, sfstat, CTLTYPE_OPAQUE | CTLFLAG_RW, 186 NULL, 0, sfstat_sysctl, "I", "sendfile statistics"); 187 188/* 189 * Convert a user file descriptor to a kernel file entry and check if required 190 * capability rights are present. 191 * A reference on the file entry is held upon returning. 192 */ |
201static int | 193int |
202getsock_cap(struct filedesc *fdp, int fd, cap_rights_t *rightsp, 203 struct file **fpp, u_int *fflagp) 204{ 205 struct file *fp; 206 int error; 207 208 error = fget_unlocked(fdp, fd, rightsp, 0, &fp, NULL); 209 if (error != 0) --- 2991 unchanged lines hidden (view full) --- 3201 if (m) 3202 m_freem(m); 3203 3204 if (error == ERESTART) 3205 error = EINTR; 3206 3207 return (error); 3208} | 194getsock_cap(struct filedesc *fdp, int fd, cap_rights_t *rightsp, 195 struct file **fpp, u_int *fflagp) 196{ 197 struct file *fp; 198 int error; 199 200 error = fget_unlocked(fdp, fd, rightsp, 0, &fp, NULL); 201 if (error != 0) --- 2991 unchanged lines hidden (view full) --- 3193 if (m) 3194 m_freem(m); 3195 3196 if (error == ERESTART) 3197 error = EINTR; 3198 3199 return (error); 3200} |
3209 3210/* 3211 * SCTP syscalls. 3212 * Functionality only compiled in if SCTP is defined in the kernel Makefile, 3213 * otherwise all return EOPNOTSUPP. 3214 * XXX: We should make this loadable one day. 3215 */ 3216int 3217sys_sctp_peeloff(td, uap) 3218 struct thread *td; 3219 struct sctp_peeloff_args /* { 3220 int sd; 3221 caddr_t name; 3222 } */ *uap; 3223{ 3224#if (defined(INET) || defined(INET6)) && defined(SCTP) 3225 struct file *nfp = NULL; 3226 struct socket *head, *so; 3227 cap_rights_t rights; 3228 u_int fflag; 3229 int error, fd; 3230 3231 AUDIT_ARG_FD(uap->sd); 3232 error = fgetsock(td, uap->sd, cap_rights_init(&rights, CAP_PEELOFF), 3233 &head, &fflag); 3234 if (error != 0) 3235 goto done2; 3236 if (head->so_proto->pr_protocol != IPPROTO_SCTP) { 3237 error = EOPNOTSUPP; 3238 goto done; 3239 } 3240 error = sctp_can_peel_off(head, (sctp_assoc_t)uap->name); 3241 if (error != 0) 3242 goto done; 3243 /* 3244 * At this point we know we do have a assoc to pull 3245 * we proceed to get the fd setup. This may block 3246 * but that is ok. 3247 */ 3248 3249 error = falloc(td, &nfp, &fd, 0); 3250 if (error != 0) 3251 goto done; 3252 td->td_retval[0] = fd; 3253 3254 CURVNET_SET(head->so_vnet); 3255 so = sonewconn(head, SS_ISCONNECTED); 3256 if (so == NULL) { 3257 error = ENOMEM; 3258 goto noconnection; 3259 } 3260 /* 3261 * Before changing the flags on the socket, we have to bump the 3262 * reference count. Otherwise, if the protocol calls sofree(), 3263 * the socket will be released due to a zero refcount. 3264 */ 3265 SOCK_LOCK(so); 3266 soref(so); /* file descriptor reference */ 3267 SOCK_UNLOCK(so); 3268 3269 ACCEPT_LOCK(); 3270 3271 TAILQ_REMOVE(&head->so_comp, so, so_list); 3272 head->so_qlen--; 3273 so->so_state |= (head->so_state & SS_NBIO); 3274 so->so_state &= ~SS_NOFDREF; 3275 so->so_qstate &= ~SQ_COMP; 3276 so->so_head = NULL; 3277 ACCEPT_UNLOCK(); 3278 finit(nfp, fflag, DTYPE_SOCKET, so, &socketops); 3279 error = sctp_do_peeloff(head, so, (sctp_assoc_t)uap->name); 3280 if (error != 0) 3281 goto noconnection; 3282 if (head->so_sigio != NULL) 3283 fsetown(fgetown(&head->so_sigio), &so->so_sigio); 3284 3285noconnection: 3286 /* 3287 * close the new descriptor, assuming someone hasn't ripped it 3288 * out from under us. 3289 */ 3290 if (error != 0) 3291 fdclose(td->td_proc->p_fd, nfp, fd, td); 3292 3293 /* 3294 * Release explicitly held references before returning. 3295 */ 3296 CURVNET_RESTORE(); 3297done: 3298 if (nfp != NULL) 3299 fdrop(nfp, td); 3300 fputsock(head); 3301done2: 3302 return (error); 3303#else /* SCTP */ 3304 return (EOPNOTSUPP); 3305#endif /* SCTP */ 3306} 3307 3308int 3309sys_sctp_generic_sendmsg (td, uap) 3310 struct thread *td; 3311 struct sctp_generic_sendmsg_args /* { 3312 int sd, 3313 caddr_t msg, 3314 int mlen, 3315 caddr_t to, 3316 __socklen_t tolen, 3317 struct sctp_sndrcvinfo *sinfo, 3318 int flags 3319 } */ *uap; 3320{ 3321#if (defined(INET) || defined(INET6)) && defined(SCTP) 3322 struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL; 3323 struct socket *so; 3324 struct file *fp = NULL; 3325 struct sockaddr *to = NULL; 3326#ifdef KTRACE 3327 struct uio *ktruio = NULL; 3328#endif 3329 struct uio auio; 3330 struct iovec iov[1]; 3331 cap_rights_t rights; 3332 int error = 0, len; 3333 3334 if (uap->sinfo != NULL) { 3335 error = copyin(uap->sinfo, &sinfo, sizeof (sinfo)); 3336 if (error != 0) 3337 return (error); 3338 u_sinfo = &sinfo; 3339 } 3340 3341 cap_rights_init(&rights, CAP_SEND); 3342 if (uap->tolen != 0) { 3343 error = getsockaddr(&to, uap->to, uap->tolen); 3344 if (error != 0) { 3345 to = NULL; 3346 goto sctp_bad2; 3347 } 3348 cap_rights_set(&rights, CAP_CONNECT); 3349 } 3350 3351 AUDIT_ARG_FD(uap->sd); 3352 error = getsock_cap(td->td_proc->p_fd, uap->sd, &rights, &fp, NULL); 3353 if (error != 0) 3354 goto sctp_bad; 3355#ifdef KTRACE 3356 if (to && (KTRPOINT(td, KTR_STRUCT))) 3357 ktrsockaddr(to); 3358#endif 3359 3360 iov[0].iov_base = uap->msg; 3361 iov[0].iov_len = uap->mlen; 3362 3363 so = (struct socket *)fp->f_data; 3364 if (so->so_proto->pr_protocol != IPPROTO_SCTP) { 3365 error = EOPNOTSUPP; 3366 goto sctp_bad; 3367 } 3368#ifdef MAC 3369 error = mac_socket_check_send(td->td_ucred, so); 3370 if (error != 0) 3371 goto sctp_bad; 3372#endif /* MAC */ 3373 3374 auio.uio_iov = iov; 3375 auio.uio_iovcnt = 1; 3376 auio.uio_segflg = UIO_USERSPACE; 3377 auio.uio_rw = UIO_WRITE; 3378 auio.uio_td = td; 3379 auio.uio_offset = 0; /* XXX */ 3380 auio.uio_resid = 0; 3381 len = auio.uio_resid = uap->mlen; 3382 CURVNET_SET(so->so_vnet); 3383 error = sctp_lower_sosend(so, to, &auio, (struct mbuf *)NULL, 3384 (struct mbuf *)NULL, uap->flags, u_sinfo, td); 3385 CURVNET_RESTORE(); 3386 if (error != 0) { 3387 if (auio.uio_resid != len && (error == ERESTART || 3388 error == EINTR || error == EWOULDBLOCK)) 3389 error = 0; 3390 /* Generation of SIGPIPE can be controlled per socket. */ 3391 if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) && 3392 !(uap->flags & MSG_NOSIGNAL)) { 3393 PROC_LOCK(td->td_proc); 3394 tdsignal(td, SIGPIPE); 3395 PROC_UNLOCK(td->td_proc); 3396 } 3397 } 3398 if (error == 0) 3399 td->td_retval[0] = len - auio.uio_resid; 3400#ifdef KTRACE 3401 if (ktruio != NULL) { 3402 ktruio->uio_resid = td->td_retval[0]; 3403 ktrgenio(uap->sd, UIO_WRITE, ktruio, error); 3404 } 3405#endif /* KTRACE */ 3406sctp_bad: 3407 if (fp != NULL) 3408 fdrop(fp, td); 3409sctp_bad2: 3410 free(to, M_SONAME); 3411 return (error); 3412#else /* SCTP */ 3413 return (EOPNOTSUPP); 3414#endif /* SCTP */ 3415} 3416 3417int 3418sys_sctp_generic_sendmsg_iov(td, uap) 3419 struct thread *td; 3420 struct sctp_generic_sendmsg_iov_args /* { 3421 int sd, 3422 struct iovec *iov, 3423 int iovlen, 3424 caddr_t to, 3425 __socklen_t tolen, 3426 struct sctp_sndrcvinfo *sinfo, 3427 int flags 3428 } */ *uap; 3429{ 3430#if (defined(INET) || defined(INET6)) && defined(SCTP) 3431 struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL; 3432 struct socket *so; 3433 struct file *fp = NULL; 3434 struct sockaddr *to = NULL; 3435#ifdef KTRACE 3436 struct uio *ktruio = NULL; 3437#endif 3438 struct uio auio; 3439 struct iovec *iov, *tiov; 3440 cap_rights_t rights; 3441 ssize_t len; 3442 int error, i; 3443 3444 if (uap->sinfo != NULL) { 3445 error = copyin(uap->sinfo, &sinfo, sizeof (sinfo)); 3446 if (error != 0) 3447 return (error); 3448 u_sinfo = &sinfo; 3449 } 3450 cap_rights_init(&rights, CAP_SEND); 3451 if (uap->tolen != 0) { 3452 error = getsockaddr(&to, uap->to, uap->tolen); 3453 if (error != 0) { 3454 to = NULL; 3455 goto sctp_bad2; 3456 } 3457 cap_rights_set(&rights, CAP_CONNECT); 3458 } 3459 3460 AUDIT_ARG_FD(uap->sd); 3461 error = getsock_cap(td->td_proc->p_fd, uap->sd, &rights, &fp, NULL); 3462 if (error != 0) 3463 goto sctp_bad1; 3464 3465#ifdef COMPAT_FREEBSD32 3466 if (SV_CURPROC_FLAG(SV_ILP32)) 3467 error = freebsd32_copyiniov((struct iovec32 *)uap->iov, 3468 uap->iovlen, &iov, EMSGSIZE); 3469 else 3470#endif 3471 error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE); 3472 if (error != 0) 3473 goto sctp_bad1; 3474#ifdef KTRACE 3475 if (to && (KTRPOINT(td, KTR_STRUCT))) 3476 ktrsockaddr(to); 3477#endif 3478 3479 so = (struct socket *)fp->f_data; 3480 if (so->so_proto->pr_protocol != IPPROTO_SCTP) { 3481 error = EOPNOTSUPP; 3482 goto sctp_bad; 3483 } 3484#ifdef MAC 3485 error = mac_socket_check_send(td->td_ucred, so); 3486 if (error != 0) 3487 goto sctp_bad; 3488#endif /* MAC */ 3489 3490 auio.uio_iov = iov; 3491 auio.uio_iovcnt = uap->iovlen; 3492 auio.uio_segflg = UIO_USERSPACE; 3493 auio.uio_rw = UIO_WRITE; 3494 auio.uio_td = td; 3495 auio.uio_offset = 0; /* XXX */ 3496 auio.uio_resid = 0; 3497 tiov = iov; 3498 for (i = 0; i <uap->iovlen; i++, tiov++) { 3499 if ((auio.uio_resid += tiov->iov_len) < 0) { 3500 error = EINVAL; 3501 goto sctp_bad; 3502 } 3503 } 3504 len = auio.uio_resid; 3505 CURVNET_SET(so->so_vnet); 3506 error = sctp_lower_sosend(so, to, &auio, 3507 (struct mbuf *)NULL, (struct mbuf *)NULL, 3508 uap->flags, u_sinfo, td); 3509 CURVNET_RESTORE(); 3510 if (error != 0) { 3511 if (auio.uio_resid != len && (error == ERESTART || 3512 error == EINTR || error == EWOULDBLOCK)) 3513 error = 0; 3514 /* Generation of SIGPIPE can be controlled per socket */ 3515 if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) && 3516 !(uap->flags & MSG_NOSIGNAL)) { 3517 PROC_LOCK(td->td_proc); 3518 tdsignal(td, SIGPIPE); 3519 PROC_UNLOCK(td->td_proc); 3520 } 3521 } 3522 if (error == 0) 3523 td->td_retval[0] = len - auio.uio_resid; 3524#ifdef KTRACE 3525 if (ktruio != NULL) { 3526 ktruio->uio_resid = td->td_retval[0]; 3527 ktrgenio(uap->sd, UIO_WRITE, ktruio, error); 3528 } 3529#endif /* KTRACE */ 3530sctp_bad: 3531 free(iov, M_IOV); 3532sctp_bad1: 3533 if (fp != NULL) 3534 fdrop(fp, td); 3535sctp_bad2: 3536 free(to, M_SONAME); 3537 return (error); 3538#else /* SCTP */ 3539 return (EOPNOTSUPP); 3540#endif /* SCTP */ 3541} 3542 3543int 3544sys_sctp_generic_recvmsg(td, uap) 3545 struct thread *td; 3546 struct sctp_generic_recvmsg_args /* { 3547 int sd, 3548 struct iovec *iov, 3549 int iovlen, 3550 struct sockaddr *from, 3551 __socklen_t *fromlenaddr, 3552 struct sctp_sndrcvinfo *sinfo, 3553 int *msg_flags 3554 } */ *uap; 3555{ 3556#if (defined(INET) || defined(INET6)) && defined(SCTP) 3557 uint8_t sockbufstore[256]; 3558 struct uio auio; 3559 struct iovec *iov, *tiov; 3560 struct sctp_sndrcvinfo sinfo; 3561 struct socket *so; 3562 struct file *fp = NULL; 3563 struct sockaddr *fromsa; 3564 cap_rights_t rights; 3565#ifdef KTRACE 3566 struct uio *ktruio = NULL; 3567#endif 3568 ssize_t len; 3569 int error, fromlen, i, msg_flags; 3570 3571 AUDIT_ARG_FD(uap->sd); 3572 error = getsock_cap(td->td_proc->p_fd, uap->sd, 3573 cap_rights_init(&rights, CAP_RECV), &fp, NULL); 3574 if (error != 0) 3575 return (error); 3576#ifdef COMPAT_FREEBSD32 3577 if (SV_CURPROC_FLAG(SV_ILP32)) 3578 error = freebsd32_copyiniov((struct iovec32 *)uap->iov, 3579 uap->iovlen, &iov, EMSGSIZE); 3580 else 3581#endif 3582 error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE); 3583 if (error != 0) 3584 goto out1; 3585 3586 so = fp->f_data; 3587 if (so->so_proto->pr_protocol != IPPROTO_SCTP) { 3588 error = EOPNOTSUPP; 3589 goto out; 3590 } 3591#ifdef MAC 3592 error = mac_socket_check_receive(td->td_ucred, so); 3593 if (error != 0) 3594 goto out; 3595#endif /* MAC */ 3596 3597 if (uap->fromlenaddr != NULL) { 3598 error = copyin(uap->fromlenaddr, &fromlen, sizeof (fromlen)); 3599 if (error != 0) 3600 goto out; 3601 } else { 3602 fromlen = 0; 3603 } 3604 if (uap->msg_flags) { 3605 error = copyin(uap->msg_flags, &msg_flags, sizeof (int)); 3606 if (error != 0) 3607 goto out; 3608 } else { 3609 msg_flags = 0; 3610 } 3611 auio.uio_iov = iov; 3612 auio.uio_iovcnt = uap->iovlen; 3613 auio.uio_segflg = UIO_USERSPACE; 3614 auio.uio_rw = UIO_READ; 3615 auio.uio_td = td; 3616 auio.uio_offset = 0; /* XXX */ 3617 auio.uio_resid = 0; 3618 tiov = iov; 3619 for (i = 0; i <uap->iovlen; i++, tiov++) { 3620 if ((auio.uio_resid += tiov->iov_len) < 0) { 3621 error = EINVAL; 3622 goto out; 3623 } 3624 } 3625 len = auio.uio_resid; 3626 fromsa = (struct sockaddr *)sockbufstore; 3627 3628#ifdef KTRACE 3629 if (KTRPOINT(td, KTR_GENIO)) 3630 ktruio = cloneuio(&auio); 3631#endif /* KTRACE */ 3632 memset(&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); 3633 CURVNET_SET(so->so_vnet); 3634 error = sctp_sorecvmsg(so, &auio, (struct mbuf **)NULL, 3635 fromsa, fromlen, &msg_flags, 3636 (struct sctp_sndrcvinfo *)&sinfo, 1); 3637 CURVNET_RESTORE(); 3638 if (error != 0) { 3639 if (auio.uio_resid != len && (error == ERESTART || 3640 error == EINTR || error == EWOULDBLOCK)) 3641 error = 0; 3642 } else { 3643 if (uap->sinfo) 3644 error = copyout(&sinfo, uap->sinfo, sizeof (sinfo)); 3645 } 3646#ifdef KTRACE 3647 if (ktruio != NULL) { 3648 ktruio->uio_resid = len - auio.uio_resid; 3649 ktrgenio(uap->sd, UIO_READ, ktruio, error); 3650 } 3651#endif /* KTRACE */ 3652 if (error != 0) 3653 goto out; 3654 td->td_retval[0] = len - auio.uio_resid; 3655 3656 if (fromlen && uap->from) { 3657 len = fromlen; 3658 if (len <= 0 || fromsa == 0) 3659 len = 0; 3660 else { 3661 len = MIN(len, fromsa->sa_len); 3662 error = copyout(fromsa, uap->from, (size_t)len); 3663 if (error != 0) 3664 goto out; 3665 } 3666 error = copyout(&len, uap->fromlenaddr, sizeof (socklen_t)); 3667 if (error != 0) 3668 goto out; 3669 } 3670#ifdef KTRACE 3671 if (KTRPOINT(td, KTR_STRUCT)) 3672 ktrsockaddr(fromsa); 3673#endif 3674 if (uap->msg_flags) { 3675 error = copyout(&msg_flags, uap->msg_flags, sizeof (int)); 3676 if (error != 0) 3677 goto out; 3678 } 3679out: 3680 free(iov, M_IOV); 3681out1: 3682 if (fp != NULL) 3683 fdrop(fp, td); 3684 3685 return (error); 3686#else /* SCTP */ 3687 return (EOPNOTSUPP); 3688#endif /* SCTP */ 3689} | |