From 75b706fde4cbf82bcd41a1cec319778aa0f8eb2d Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 9 Dec 2016 14:19:03 +0100 Subject: Update to FreeBSD head 2016-12-10 Git mirror commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c. --- freebsd/sys/kern/uipc_syscalls.c | 310 +++++++++------------------------------ 1 file changed, 71 insertions(+), 239 deletions(-) (limited to 'freebsd/sys/kern/uipc_syscalls.c') diff --git a/freebsd/sys/kern/uipc_syscalls.c b/freebsd/sys/kern/uipc_syscalls.c index 99ae6392..2d81fc20 100644 --- a/freebsd/sys/kern/uipc_syscalls.c +++ b/freebsd/sys/kern/uipc_syscalls.c @@ -12,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -94,20 +94,23 @@ static int sockargs(struct mbuf **, char *, socklen_t, int); /* * Convert a user file descriptor to a kernel file entry and check if required * capability rights are present. + * If required copy of current set of capability rights is returned. * A reference on the file entry is held upon returning. */ int getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp, - struct file **fpp, u_int *fflagp) + struct file **fpp, u_int *fflagp, struct filecaps *havecapsp) { struct file *fp; int error; - error = fget_unlocked(td->td_proc->p_fd, fd, rightsp, &fp, NULL); + error = fget_cap(td, fd, rightsp, &fp, havecapsp); if (error != 0) return (error); if (fp->f_type != DTYPE_SOCKET) { fdrop(fp, td); + if (havecapsp != NULL) + filecaps_free(havecapsp); return (ENOTSOCK); } if (fflagp != NULL) @@ -148,7 +151,7 @@ rtems_bsd_getsock(int fd, struct file **fpp, u_int *fflagp) return (error); } -#define getsock_cap(td, fd, rights, fpp, fflagp) rtems_bsd_getsock(fd, fpp, fflagp) +#define getsock_cap(td, fd, rights, fpp, fflagp, havecapsp) rtems_bsd_getsock(fd, fpp, fflagp) #endif /* __rtems__ */ /* @@ -162,13 +165,7 @@ rtems_bsd_getsock(int fd, struct file **fpp, u_int *fflagp) static #endif /* __rtems__ */ int -sys_socket(td, uap) - struct thread *td; - struct socket_args /* { - int domain; - int type; - int protocol; - } */ *uap; +sys_socket(struct thread *td, struct socket_args *uap) { struct socket *so; struct file *fp; @@ -239,7 +236,6 @@ socket(int domain, int type, int protocol) } #endif /* __rtems__ */ -/* ARGSUSED */ #ifdef __rtems__ static int kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa); @@ -247,13 +243,7 @@ static int kern_bindat(struct thread *td, int dirfd, int fd, static #endif /* __rtems__ */ int -sys_bind(td, uap) - struct thread *td; - struct bind_args /* { - int s; - caddr_t name; - int namelen; - } */ *uap; +sys_bind(struct thread *td, struct bind_args *uap) { struct sockaddr *sa; int error; @@ -298,7 +288,7 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) AUDIT_ARG_FD(fd); AUDIT_ARG_SOCKADDR(td, dirfd, sa); error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_BIND), - &fp, NULL); + &fp, NULL, NULL); if (error != 0) return (error); so = fp->f_data; @@ -321,18 +311,10 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) return (error); } -/* ARGSUSED */ #ifndef __rtems__ static int -sys_bindat(td, uap) - struct thread *td; - struct bindat_args /* { - int fd; - int s; - caddr_t name; - int namelen; - } */ *uap; +sys_bindat(struct thread *td, struct bindat_args *uap) { struct sockaddr *sa; int error; @@ -346,14 +328,8 @@ sys_bindat(td, uap) } #endif /* __rtems__ */ -/* ARGSUSED */ int -sys_listen(td, uap) - struct thread *td; - struct listen_args /* { - int s; - int backlog; - } */ *uap; +sys_listen(struct thread *td, struct listen_args *uap) { struct socket *so; struct file *fp; @@ -362,7 +338,7 @@ sys_listen(td, uap) AUDIT_ARG_FD(uap->s); error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_LISTEN), - &fp, NULL); + &fp, NULL, NULL); if (error == 0) { so = fp->f_data; #ifdef MAC @@ -483,6 +459,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, struct file *headfp, *nfp = NULL; struct sockaddr *sa = NULL; struct socket *head, *so; + struct filecaps fcaps; cap_rights_t rights; u_int fflag; pid_t pgid; @@ -493,7 +470,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, AUDIT_ARG_FD(s); error = getsock_cap(td, s, cap_rights_init(&rights, CAP_ACCEPT), - &headfp, &fflag); + &headfp, &fflag, &fcaps); if (error != 0) return (error); head = headfp->f_data; @@ -506,7 +483,8 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, if (error != 0) goto done; #endif - error = falloc(td, &nfp, &fd, (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0); + error = falloc_caps(td, &nfp, &fd, + (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0, &fcaps); if (error != 0) goto done; ACCEPT_LOCK(); @@ -615,6 +593,8 @@ noconnection: * a reference on nfp to the caller on success if they request it. */ done: + if (nfp == NULL) + filecaps_free(&fcaps); if (fp != NULL) { if (error == 0) { *fp = nfp; @@ -663,7 +643,6 @@ oaccept(td, uap) #endif /* COMPAT_OLDSOCK */ #endif /* __rtems__ */ -/* ARGSUSED */ #ifdef __rtems__ static int kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa); @@ -671,13 +650,7 @@ static int kern_connectat(struct thread *td, int dirfd, int fd, static #endif /* __rtems__ */ int -sys_connect(td, uap) - struct thread *td; - struct connect_args /* { - int s; - caddr_t name; - int namelen; - } */ *uap; +sys_connect(struct thread *td, struct connect_args *uap) { struct sockaddr *sa; int error; @@ -722,7 +695,7 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) AUDIT_ARG_FD(fd); AUDIT_ARG_SOCKADDR(td, dirfd, sa); error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_CONNECT), - &fp, NULL); + &fp, NULL, NULL); if (error != 0) return (error); so = fp->f_data; @@ -775,16 +748,8 @@ done1: } #ifndef __rtems__ -/* ARGSUSED */ int -sys_connectat(td, uap) - struct thread *td; - struct connectat_args /* { - int fd; - int s; - caddr_t name; - int namelen; - } */ *uap; +sys_connectat(struct thread *td, struct connectat_args *uap) { struct sockaddr *sa; int error; @@ -936,11 +901,7 @@ kern_sendit( struct thread *td, int s, struct msghdr *mp, int flags, struct mbuf *control, enum uio_seg segflg); #endif /* __rtems__ */ static int -sendit(td, s, mp, flags) - struct thread *td; - int s; - struct msghdr *mp; - int flags; +sendit(struct thread *td, int s, struct msghdr *mp, int flags) { struct mbuf *control; struct sockaddr *to; @@ -998,13 +959,8 @@ bad: } int -kern_sendit(td, s, mp, flags, control, segflg) - struct thread *td; - int s; - struct msghdr *mp; - int flags; - struct mbuf *control; - enum uio_seg segflg; +kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags, + struct mbuf *control, enum uio_seg segflg) { struct file *fp; struct uio auio; @@ -1026,12 +982,12 @@ kern_sendit(td, s, mp, flags, control, segflg) AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name); cap_rights_set(&rights, CAP_CONNECT); } - error = getsock_cap(td, s, &rights, &fp, NULL); - if (error != 0) #endif /* __rtems__ */ - error = getsock_cap(td->td_proc->p_fd, s, rights, &fp, NULL); - if (error) + error = getsock_cap(td, s, &rights, &fp, NULL, NULL); + if (error != 0) { + m_freem(control); return (error); + } so = (struct socket *)fp->f_data; #ifdef KTRACE @@ -1042,12 +998,16 @@ kern_sendit(td, s, mp, flags, control, segflg) if (mp->msg_name != NULL) { error = mac_socket_check_connect(td->td_ucred, so, mp->msg_name); - if (error != 0) + if (error != 0) { + m_freem(control); goto bad; + } } error = mac_socket_check_send(td->td_ucred, so); - if (error != 0) + if (error != 0) { + m_freem(control); goto bad; + } #endif auio.uio_iov = mp->msg_iov; @@ -1061,6 +1021,7 @@ kern_sendit(td, s, mp, flags, control, segflg) for (i = 0; i < mp->msg_iovlen; i++, iov++) { if ((auio.uio_resid += iov->iov_len) < 0) { error = EINVAL; + m_freem(control); goto bad; } } @@ -1103,16 +1064,7 @@ bad: static #endif /* __rtems__ */ int -sys_sendto(td, uap) - struct thread *td; - struct sendto_args /* { - int s; - caddr_t buf; - size_t len; - int flags; - caddr_t to; - int tolen; - } */ *uap; +sys_sendto(struct thread *td, struct sendto_args *uap) { struct msghdr msg; struct iovec aiov; @@ -1167,7 +1119,7 @@ rtems_bsd_sendto(int socket, struct mbuf *m, int flags, struct socket *so; int error; - error = getsock_cap(td->td_proc->p_fd, socket, CAP_WRITE, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, socket, CAP_WRITE, &fp, NULL, NULL); if (error) return (error); so = (struct socket *)fp->f_data; @@ -1186,14 +1138,7 @@ rtems_bsd_sendto(int socket, struct mbuf *m, int flags, #ifndef __rtems__ #ifdef COMPAT_OLDSOCK int -osend(td, uap) - struct thread *td; - struct osend_args /* { - int s; - caddr_t buf; - int len; - int flags; - } */ *uap; +osend(struct thread *td, struct osend_args *uap) { struct msghdr msg; struct iovec aiov; @@ -1210,13 +1155,7 @@ osend(td, uap) } int -osendmsg(td, uap) - struct thread *td; - struct osendmsg_args /* { - int s; - caddr_t msg; - int flags; - } */ *uap; +osendmsg(struct thread *td, struct osendmsg_args *uap) { struct msghdr msg; struct iovec *iov; @@ -1241,13 +1180,7 @@ osendmsg(td, uap) static #endif /* __rtems__ */ int -sys_sendmsg(td, uap) - struct thread *td; - struct sendmsg_args /* { - int s; - caddr_t msg; - int flags; - } */ *uap; +sys_sendmsg(struct thread *td, struct sendmsg_args *uap) { struct msghdr msg; struct iovec *iov; @@ -1297,12 +1230,8 @@ sendmsg(int socket, const struct msghdr *message, int flags) static #endif /* __rtems__ */ int -kern_recvit(td, s, mp, fromseg, controlp) - struct thread *td; - int s; - struct msghdr *mp; - enum uio_seg fromseg; - struct mbuf **controlp; +kern_recvit(struct thread *td, int s, struct msghdr *mp, enum uio_seg fromseg, + struct mbuf **controlp) { struct uio auio; struct iovec *iov; @@ -1323,7 +1252,7 @@ kern_recvit(td, s, mp, fromseg, controlp) AUDIT_ARG_FD(s); error = getsock_cap(td, s, cap_rights_init(&rights, CAP_RECV), - &fp, NULL); + &fp, NULL, NULL); if (error != 0) return (error); so = fp->f_data; @@ -1459,11 +1388,7 @@ out: } static int -recvit(td, s, mp, namelenp) - struct thread *td; - int s; - struct msghdr *mp; - void *namelenp; +recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp) { int error; @@ -1484,16 +1409,7 @@ recvit(td, s, mp, namelenp) static #endif /* __rtems__ */ int -sys_recvfrom(td, uap) - struct thread *td; - struct recvfrom_args /* { - int s; - caddr_t buf; - size_t len; - int flags; - struct sockaddr * __restrict from; - socklen_t * __restrict fromlenaddr; - } */ *uap; +sys_recvfrom(struct thread *td, struct recvfrom_args *uap) { struct msghdr msg; struct iovec aiov; @@ -1551,9 +1467,7 @@ recvfrom(int socket, void *__restrict buffer, size_t length, int flags, #ifndef __rtems__ #ifdef COMPAT_OLDSOCK int -orecvfrom(td, uap) - struct thread *td; - struct recvfrom_args *uap; +orecvfrom(struct thread *td, struct recvfrom_args *uap) { uap->flags |= MSG_COMPAT; @@ -1563,14 +1477,7 @@ orecvfrom(td, uap) #ifdef COMPAT_OLDSOCK int -orecv(td, uap) - struct thread *td; - struct orecv_args /* { - int s; - caddr_t buf; - int len; - int flags; - } */ *uap; +orecv(struct thread *td, struct orecv_args *uap) { struct msghdr msg; struct iovec aiov; @@ -1592,13 +1499,7 @@ orecv(td, uap) * rights where the control fields are now. */ int -orecvmsg(td, uap) - struct thread *td; - struct orecvmsg_args /* { - int s; - struct omsghdr *msg; - int flags; - } */ *uap; +orecvmsg(struct thread *td, struct orecvmsg_args *uap) { struct msghdr msg; struct iovec *iov; @@ -1626,13 +1527,7 @@ orecvmsg(td, uap) static #endif /* __rtems__ */ int -sys_recvmsg(td, uap) - struct thread *td; - struct recvmsg_args /* { - int s; - struct msghdr *msg; - int flags; - } */ *uap; +sys_recvmsg(struct thread *td, struct recvmsg_args *uap) { struct msghdr msg; struct iovec *uiov, *iov; @@ -1684,17 +1579,11 @@ recvmsg(int socket, struct msghdr *message, int flags) } #endif /* __rtems__ */ -/* ARGSUSED */ #ifdef __rtems__ static #endif /* __rtems__ */ int -sys_shutdown(td, uap) - struct thread *td; - struct shutdown_args /* { - int s; - int how; - } */ *uap; +sys_shutdown(struct thread *td, struct shutdown_args *uap) { struct socket *so; struct file *fp; @@ -1703,7 +1592,7 @@ sys_shutdown(td, uap) AUDIT_ARG_FD(uap->s); error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_SHUTDOWN), - &fp, NULL); + &fp, NULL, NULL); if (error == 0) { so = fp->f_data; error = soshutdown(so, uap->how); @@ -1736,7 +1625,6 @@ shutdown(int socket, int how) } #endif /* __rtems__ */ -/* ARGSUSED */ #ifdef __rtems__ static int kern_setsockopt( struct thread *td, int s, int level, int name, void *val, enum uio_seg valseg, socklen_t valsize); @@ -1744,15 +1632,7 @@ static int kern_setsockopt( struct thread *td, int s, int level, int name, static #endif /* __rtems__ */ int -sys_setsockopt(td, uap) - struct thread *td; - struct setsockopt_args /* { - int s; - int level; - int name; - caddr_t val; - int valsize; - } */ *uap; +sys_setsockopt(struct thread *td, struct setsockopt_args *uap) { return (kern_setsockopt(td, uap->s, uap->level, uap->name, @@ -1784,14 +1664,8 @@ setsockopt(int socket, int level, int option_name, const void *option_value, #endif /* __rtems__ */ int -kern_setsockopt(td, s, level, name, val, valseg, valsize) - struct thread *td; - int s; - int level; - int name; - void *val; - enum uio_seg valseg; - socklen_t valsize; +kern_setsockopt(struct thread *td, int s, int level, int name, void *val, + enum uio_seg valseg, socklen_t valsize) { struct socket *so; struct file *fp; @@ -1822,7 +1696,7 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize) AUDIT_ARG_FD(s); error = getsock_cap(td, s, cap_rights_init(&rights, CAP_SETSOCKOPT), - &fp, NULL); + &fp, NULL, NULL); if (error == 0) { so = fp->f_data; error = sosetopt(so, &sopt); @@ -1831,7 +1705,6 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize) return(error); } -/* ARGSUSED */ #ifdef __rtems__ static int kern_getsockopt( struct thread *td, int s, int level, int name, void *val, enum uio_seg valseg, socklen_t *valsize); @@ -1839,15 +1712,7 @@ static int kern_getsockopt( struct thread *td, int s, int level, int name, static #endif /* __rtems__ */ int -sys_getsockopt(td, uap) - struct thread *td; - struct getsockopt_args /* { - int s; - int level; - int name; - void * __restrict val; - socklen_t * __restrict avalsize; - } */ *uap; +sys_getsockopt(struct thread *td, struct getsockopt_args *uap) { socklen_t valsize; int error; @@ -1895,14 +1760,8 @@ getsockopt(int socket, int level, int option_name, void *__restrict * optval can be a userland or userspace. optlen is always a kernel pointer. */ int -kern_getsockopt(td, s, level, name, val, valseg, valsize) - struct thread *td; - int s; - int level; - int name; - void *val; - enum uio_seg valseg; - socklen_t *valsize; +kern_getsockopt(struct thread *td, int s, int level, int name, void *val, + enum uio_seg valseg, socklen_t *valsize) { struct socket *so; struct file *fp; @@ -1933,7 +1792,7 @@ kern_getsockopt(td, s, level, name, val, valseg, valsize) AUDIT_ARG_FD(s); error = getsock_cap(td, s, cap_rights_init(&rights, CAP_GETSOCKOPT), - &fp, NULL); + &fp, NULL, NULL); if (error == 0) { so = fp->f_data; error = sogetopt(so, &sopt); @@ -1951,16 +1810,8 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, /* * getsockname1() - Get socket name. */ -/* ARGSUSED */ static int -getsockname1(td, uap, compat) - struct thread *td; - struct getsockname_args /* { - int fdes; - struct sockaddr * __restrict asa; - socklen_t * __restrict alen; - } */ *uap; - int compat; +getsockname1(struct thread *td, struct getsockname_args *uap, int compat) { struct sockaddr *sa; socklen_t len; @@ -2000,7 +1851,7 @@ getsockname(int socket, struct sockaddr *__restrict address, int error; if (td != NULL) { - error = getsockname1(td, &ua); + error = getsockname1(td, &ua, 0); } else { error = ENOMEM; } @@ -2021,7 +1872,7 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, AUDIT_ARG_FD(fd); error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETSOCKNAME), - &fp, NULL); + &fp, NULL, NULL); if (error != 0) return (error); so = fp->f_data; @@ -2051,9 +1902,7 @@ bad: #ifndef __rtems__ int -sys_getsockname(td, uap) - struct thread *td; - struct getsockname_args *uap; +sys_getsockname(struct thread *td, struct getsockname_args *uap) { return (getsockname1(td, uap, 0)); @@ -2061,9 +1910,7 @@ sys_getsockname(td, uap) #ifdef COMPAT_OLDSOCK int -ogetsockname(td, uap) - struct thread *td; - struct getsockname_args *uap; +ogetsockname(struct thread *td, struct getsockname_args *uap) { return (getsockname1(td, uap, 1)); @@ -2079,16 +1926,8 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa, /* * getpeername1() - Get name of peer for connected socket. */ -/* ARGSUSED */ static int -getpeername1(td, uap, compat) - struct thread *td; - struct getpeername_args /* { - int fdes; - struct sockaddr * __restrict asa; - socklen_t * __restrict alen; - } */ *uap; - int compat; +getpeername1(struct thread *td, struct getpeername_args *uap, int compat) { struct sockaddr *sa; socklen_t len; @@ -2128,7 +1967,7 @@ getpeername(int socket, struct sockaddr *__restrict address, int error; if (td != NULL) { - error = getpeername1(td, &ua); + error = getpeername1(td, &ua, 0); } else { error = ENOMEM; } @@ -2149,7 +1988,7 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa, AUDIT_ARG_FD(fd); error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETPEERNAME), - &fp, NULL); + &fp, NULL, NULL); if (error != 0) return (error); so = fp->f_data; @@ -2184,9 +2023,7 @@ done: #ifndef __rtems__ int -sys_getpeername(td, uap) - struct thread *td; - struct getpeername_args *uap; +sys_getpeername(struct thread *td, struct getpeername_args *uap) { return (getpeername1(td, uap, 0)); @@ -2194,9 +2031,7 @@ sys_getpeername(td, uap) #ifdef COMPAT_OLDSOCK int -ogetpeername(td, uap) - struct thread *td; - struct ogetpeername_args *uap; +ogetpeername(struct thread *td, struct ogetpeername_args *uap) { /* XXX uap should have type `getpeername_args *' to begin with. */ @@ -2242,10 +2077,7 @@ sockargs(struct mbuf **mp, char *buf, socklen_t buflen, int type) } int -getsockaddr(namp, uaddr, len) - struct sockaddr **namp; - caddr_t uaddr; - size_t len; +getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len) { struct sockaddr *sa; int error; -- cgit v1.2.3