From b8129eaf84f85d9a5cbdc81025dd8314f8148d85 Mon Sep 17 00:00:00 2001 From: dchagin Date: Wed, 15 Mar 2017 16:38:39 +0000 Subject: MFC r305093 (by mjg@): fd: add fdeget_locked and use in kern_descrip MFC r305756 (by oshogbo@): fd: add fget_cap and fget_cap_locked primitives. They can be used to obtain capabilities along with a referenced fp. MFC r306174 (by oshogbo@): capsicum: propagate rights on accept(2) Descriptor returned by accept(2) should inherits capabilities rights from the listening socket. PR: 201052 MFC r306184 (by oshogbo@): fd: simplify fgetvp_rights by using fget_cap_locked. MFC r306225 (by mjg@): fd: fix up fgetvp_rights after r306184 fget_cap_locked returns a referenced file, but the fgetvp_rights does not need it. Instead, due to the filedesc lock being held, it can ref the vnode after the file was looked up. Fix up fget_cap_locked to be consistent with other _locked helpers and not ref the file. This plugs a leak introduced in r306184. MFC r306232 (by oshogbo@): fd: fix up fget_cap If the kernel is not compiled with the CAPABILITIES kernel options fget_unlocked doesn't return the sequence number so fd_modify will always report modification, in that case we got infinity loop. MFC r311474 (by glebius@): Use getsock_cap() instead of fgetsock(). MFC r312079 (by glebius@): Use getsock_cap() instead of deprecated fgetsock(). MFC r312081 (by glebius@): Use getsock_cap() instead of deprecated fgetsock(). MFC r312087 (by glebius@): Remove deprecated fgetsock() and fputsock(). Bump __FreeBSD_version as getsock_cap changed and fgetsock/fputsock pair removed. --- sys/compat/cloudabi/cloudabi_sock.c | 2 +- sys/compat/linux/linux_socket.c | 34 +++---- sys/dev/iscsi_initiator/isc_soc.c | 1 - sys/dev/iscsi_initiator/iscsi.c | 16 +--- sys/kern/kern_descrip.c | 185 ++++++++++++++++++++---------------- sys/kern/kern_sendfile.c | 2 +- sys/kern/uipc_syscalls.c | 35 ++++--- sys/netinet/sctp_syscalls.c | 15 +-- sys/sys/file.h | 6 -- sys/sys/filedesc.h | 17 ++++ sys/sys/param.h | 2 +- sys/sys/socketvar.h | 3 +- 12 files changed, 175 insertions(+), 143 deletions(-) (limited to 'sys') diff --git a/sys/compat/cloudabi/cloudabi_sock.c b/sys/compat/cloudabi/cloudabi_sock.c index b66f0ab..c66e209 100644 --- a/sys/compat/cloudabi/cloudabi_sock.c +++ b/sys/compat/cloudabi/cloudabi_sock.c @@ -210,7 +210,7 @@ cloudabi_sys_sock_stat_get(struct thread *td, int error; error = getsock_cap(td, uap->sock, cap_rights_init(&rights, - CAP_GETSOCKOPT, CAP_GETPEERNAME, CAP_GETSOCKNAME), &fp, NULL); + CAP_GETSOCKOPT, CAP_GETPEERNAME, CAP_GETSOCKNAME), &fp, NULL, NULL); if (error != 0) return (error); so = fp->f_data; diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 7e65332..5477ece 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -775,6 +775,7 @@ linux_connect(struct thread *td, struct linux_connect_args *args) cap_rights_t rights; struct socket *so; struct sockaddr *sa; + struct file *fp; u_int fflag; int error; @@ -792,24 +793,23 @@ linux_connect(struct thread *td, struct linux_connect_args *args) * Linux doesn't return EISCONN the first time it occurs, * when on a non-blocking socket. Instead it returns the * error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD. - * - * XXXRW: Instead of using fgetsock(), check that it is a - * socket and use the file descriptor reference instead of - * creating a new one. */ - error = fgetsock(td, args->s, cap_rights_init(&rights, CAP_CONNECT), - &so, &fflag); - if (error == 0) { - error = EISCONN; - if (fflag & FNONBLOCK) { - SOCK_LOCK(so); - if (so->so_emuldata == 0) - error = so->so_error; - so->so_emuldata = (void *)1; - SOCK_UNLOCK(so); - } - fputsock(so); + error = getsock_cap(td, args->s, cap_rights_init(&rights, CAP_CONNECT), + &fp, &fflag, NULL); + if (error != 0) + return (error); + + error = EISCONN; + so = fp->f_data; + if (fflag & FNONBLOCK) { + SOCK_LOCK(so); + if (so->so_emuldata == 0) + error = so->so_error; + so->so_emuldata = (void *)1; + SOCK_UNLOCK(so); } + fdrop(fp, td); + return (error); } @@ -855,7 +855,7 @@ linux_accept_common(struct thread *td, int s, l_uintptr_t addr, if (error == EFAULT && namelen != sizeof(struct sockaddr_in)) return (EINVAL); if (error == EINVAL) { - error1 = getsock_cap(td, s, &rights, &fp, NULL); + error1 = getsock_cap(td, s, &rights, &fp, NULL, NULL); if (error1 != 0) return (error1); so = fp->f_data; diff --git a/sys/dev/iscsi_initiator/isc_soc.c b/sys/dev/iscsi_initiator/isc_soc.c index 2282677..1e25f72 100644 --- a/sys/dev/iscsi_initiator/isc_soc.c +++ b/sys/dev/iscsi_initiator/isc_soc.c @@ -680,7 +680,6 @@ isc_stop_receiver(isc_session_t *sp) if(sp->fp != NULL) fdrop(sp->fp, sp->td); - fputsock(sp->soc); sp->soc = NULL; sp->fp = NULL; diff --git a/sys/dev/iscsi_initiator/iscsi.c b/sys/dev/iscsi_initiator/iscsi.c index e607f18..ac3d1cc 100644 --- a/sys/dev/iscsi_initiator/iscsi.c +++ b/sys/dev/iscsi_initiator/iscsi.c @@ -388,20 +388,14 @@ i_setsoc(isc_session_t *sp, int fd, struct thread *td) if(sp->soc != NULL) isc_stop_receiver(sp); - error = fget(td, fd, cap_rights_init(&rights, CAP_SOCK_CLIENT), &sp->fp); + error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_SOCK_CLIENT), + &sp->fp, NULL, NULL); if(error) return error; - error = fgetsock(td, fd, cap_rights_init(&rights, CAP_SOCK_CLIENT), - &sp->soc, 0); - if(error == 0) { - sp->td = td; - isc_start_receiver(sp); - } - else { - fdrop(sp->fp, td); - sp->fp = NULL; - } + sp->soc = sp->fp->f_data; + sp->td = td; + isc_start_receiver(sp); return error; } diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 30cd545..48c6db9 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -67,7 +67,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -517,28 +516,26 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) break; case F_GETFD: + error = EBADF; FILEDESC_SLOCK(fdp); - if (fget_locked(fdp, fd) == NULL) { - FILEDESC_SUNLOCK(fdp); - error = EBADF; - break; + fde = fdeget_locked(fdp, fd); + if (fde != NULL) { + td->td_retval[0] = + (fde->fde_flags & UF_EXCLOSE) ? FD_CLOEXEC : 0; + error = 0; } - fde = &fdp->fd_ofiles[fd]; - td->td_retval[0] = - (fde->fde_flags & UF_EXCLOSE) ? FD_CLOEXEC : 0; FILEDESC_SUNLOCK(fdp); break; case F_SETFD: + error = EBADF; FILEDESC_XLOCK(fdp); - if (fget_locked(fdp, fd) == NULL) { - FILEDESC_XUNLOCK(fdp); - error = EBADF; - break; + fde = fdeget_locked(fdp, fd); + if (fde != NULL) { + fde->fde_flags = (fde->fde_flags & ~UF_EXCLOSE) | + (arg & FD_CLOEXEC ? UF_EXCLOSE : 0); + error = 0; } - fde = &fdp->fd_ofiles[fd]; - fde->fde_flags = (fde->fde_flags & ~UF_EXCLOSE) | - (arg & FD_CLOEXEC ? UF_EXCLOSE : 0); FILEDESC_XUNLOCK(fdp); break; @@ -2450,6 +2447,82 @@ finit(struct file *fp, u_int flag, short type, void *data, struct fileops *ops) } int +fget_cap_locked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp, + struct file **fpp, struct filecaps *havecapsp) +{ + struct filedescent *fde; + int error; + + FILEDESC_LOCK_ASSERT(fdp); + + fde = fdeget_locked(fdp, fd); + if (fde == NULL) { + error = EBADF; + goto out; + } + +#ifdef CAPABILITIES + error = cap_check(cap_rights_fde(fde), needrightsp); + if (error != 0) + goto out; +#endif + + if (havecapsp != NULL) + filecaps_copy(&fde->fde_caps, havecapsp, true); + + *fpp = fde->fde_file; + + error = 0; +out: + return (error); +} + +int +fget_cap(struct thread *td, int fd, cap_rights_t *needrightsp, + struct file **fpp, struct filecaps *havecapsp) +{ + struct filedesc *fdp = td->td_proc->p_fd; + int error; +#ifndef CAPABILITIES + error = fget_unlocked(fdp, fd, needrightsp, fpp, NULL); + if (error == 0 && havecapsp != NULL) + filecaps_fill(havecapsp); +#else + struct file *fp; + seq_t seq; + + for (;;) { + error = fget_unlocked(fdp, fd, needrightsp, &fp, &seq); + if (error != 0) + return (error); + + if (havecapsp != NULL) { + if (!filecaps_copy(&fdp->fd_ofiles[fd].fde_caps, + havecapsp, false)) { + fdrop(fp, td); + goto get_locked; + } + } + + if (!fd_modified(fdp, fd, seq)) + break; + fdrop(fp, td); + } + + *fpp = fp; + return (0); + +get_locked: + FILEDESC_SLOCK(fdp); + error = fget_cap_locked(fdp, fd, needrightsp, fpp, havecapsp); + if (error == 0) + fhold(*fpp); + FILEDESC_SUNLOCK(fdp); +#endif + return (error); +} + +int fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp, struct file **fpp, seq_t *seqp) { @@ -2712,30 +2785,31 @@ fgetvp_rights(struct thread *td, int fd, cap_rights_t *needrightsp, struct filecaps *havecaps, struct vnode **vpp) { struct filedesc *fdp; + struct filecaps caps; struct file *fp; -#ifdef CAPABILITIES int error; -#endif fdp = td->td_proc->p_fd; - fp = fget_locked(fdp, fd); - if (fp == NULL || fp->f_ops == &badfileops) - return (EBADF); - -#ifdef CAPABILITIES - error = cap_check(cap_rights(fdp, fd), needrightsp); + error = fget_cap_locked(fdp, fd, needrightsp, &fp, &caps); if (error != 0) return (error); -#endif - - if (fp->f_vnode == NULL) - return (EINVAL); + if (fp->f_ops == &badfileops) { + error = EBADF; + goto out; + } + if (fp->f_vnode == NULL) { + error = EINVAL; + goto out; + } + *havecaps = caps; *vpp = fp->f_vnode; vrefact(*vpp); - filecaps_copy(&fdp->fd_ofiles[fd].fde_caps, havecaps, true); return (0); +out: + filecaps_free(&caps); + return (error); } int @@ -2763,61 +2837,6 @@ fgetvp_write(struct thread *td, int fd, cap_rights_t *rightsp, #endif /* - * Like fget() but loads the underlying socket, or returns an error if the - * descriptor does not represent a socket. - * - * We bump the ref count on the returned socket. XXX Also obtain the SX lock - * in the future. - * - * Note: fgetsock() and fputsock() are deprecated, as consumers should rely - * on their file descriptor reference to prevent the socket from being free'd - * during use. - */ -int -fgetsock(struct thread *td, int fd, cap_rights_t *rightsp, struct socket **spp, - u_int *fflagp) -{ - struct file *fp; - int error; - - *spp = NULL; - if (fflagp != NULL) - *fflagp = 0; - if ((error = _fget(td, fd, &fp, 0, rightsp, NULL)) != 0) - return (error); - if (fp->f_type != DTYPE_SOCKET) { - error = ENOTSOCK; - } else { - *spp = fp->f_data; - if (fflagp) - *fflagp = fp->f_flag; - SOCK_LOCK(*spp); - soref(*spp); - SOCK_UNLOCK(*spp); - } - fdrop(fp, td); - - return (error); -} - -/* - * Drop the reference count on the socket and XXX release the SX lock in the - * future. The last reference closes the socket. - * - * Note: fputsock() is deprecated, see comment for fgetsock(). - */ -void -fputsock(struct socket *so) -{ - - ACCEPT_LOCK(); - SOCK_LOCK(so); - CURVNET_SET(so->so_vnet); - sorele(so); - CURVNET_RESTORE(); -} - -/* * Handle the last reference to a file being closed. */ int diff --git a/sys/kern/kern_sendfile.c b/sys/kern/kern_sendfile.c index 05be5f6..cbcd826 100644 --- a/sys/kern/kern_sendfile.c +++ b/sys/kern/kern_sendfile.c @@ -502,7 +502,7 @@ sendfile_getsock(struct thread *td, int s, struct file **sock_fp, * The socket must be a stream socket and connected. */ error = getsock_cap(td, s, cap_rights_init(&rights, CAP_SEND), - sock_fp, NULL); + sock_fp, NULL, NULL); if (error != 0) return (error); *so = (*sock_fp)->f_data; diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 1bcd02e..ae1e203 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -89,20 +89,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) @@ -201,7 +204,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; @@ -262,7 +265,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 @@ -335,6 +338,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; @@ -345,7 +349,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; @@ -358,7 +362,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(); @@ -467,6 +472,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; @@ -545,7 +552,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; @@ -805,7 +812,7 @@ 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); + error = getsock_cap(td, s, &rights, &fp, NULL, NULL); if (error != 0) { m_freem(control); return (error); @@ -1013,7 +1020,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; @@ -1328,7 +1335,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); @@ -1402,7 +1409,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); @@ -1483,7 +1490,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); @@ -1544,7 +1551,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; @@ -1643,7 +1650,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; diff --git a/sys/netinet/sctp_syscalls.c b/sys/netinet/sctp_syscalls.c index 5c16e8d..66df314 100644 --- a/sys/netinet/sctp_syscalls.c +++ b/sys/netinet/sctp_syscalls.c @@ -121,17 +121,18 @@ sys_sctp_peeloff(td, uap) } */ *uap; { #if (defined(INET) || defined(INET6)) && defined(SCTP) - struct file *nfp = NULL; + struct file *headfp, *nfp = NULL; struct socket *head, *so; cap_rights_t rights; u_int fflag; int error, fd; AUDIT_ARG_FD(uap->sd); - error = fgetsock(td, uap->sd, cap_rights_init(&rights, CAP_PEELOFF), - &head, &fflag); + error = getsock_cap(td, uap->sd, cap_rights_init(&rights, CAP_PEELOFF), + &headfp, &fflag, NULL); if (error != 0) goto done2; + head = headfp->f_data; if (head->so_proto->pr_protocol != IPPROTO_SCTP) { error = EOPNOTSUPP; goto done; @@ -196,7 +197,7 @@ noconnection: done: if (nfp != NULL) fdrop(nfp, td); - fputsock(head); + fdrop(headfp, td); done2: return (error); #else /* SCTP */ @@ -248,7 +249,7 @@ sys_sctp_generic_sendmsg (td, uap) } AUDIT_ARG_FD(uap->sd); - error = getsock_cap(td, uap->sd, &rights, &fp, NULL); + error = getsock_cap(td, uap->sd, &rights, &fp, NULL, NULL); if (error != 0) goto sctp_bad; #ifdef KTRACE @@ -361,7 +362,7 @@ sys_sctp_generic_sendmsg_iov(td, uap) } AUDIT_ARG_FD(uap->sd); - error = getsock_cap(td, uap->sd, &rights, &fp, NULL); + error = getsock_cap(td, uap->sd, &rights, &fp, NULL, NULL); if (error != 0) goto sctp_bad1; @@ -477,7 +478,7 @@ sys_sctp_generic_recvmsg(td, uap) AUDIT_ARG_FD(uap->sd); error = getsock_cap(td, uap->sd, cap_rights_init(&rights, CAP_RECV), - &fp, NULL); + &fp, NULL, NULL); if (error != 0) return (error); #ifdef COMPAT_FREEBSD32 diff --git a/sys/sys/file.h b/sys/sys/file.h index 6926081..c51f26a 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -50,8 +50,6 @@ struct thread; struct uio; struct knote; struct vnode; -struct socket; - #endif /* _KERNEL */ @@ -268,10 +266,6 @@ int fgetvp_read(struct thread *td, int fd, cap_rights_t *rightsp, int fgetvp_write(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp); -int fgetsock(struct thread *td, int fd, cap_rights_t *rightsp, - struct socket **spp, u_int *fflagp); -void fputsock(struct socket *sp); - static __inline int _fnoop(void) { diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index b34a2f1..dfd81a4 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -190,6 +190,11 @@ int getvnode(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp); void mountcheckdirs(struct vnode *olddp, struct vnode *newdp); +int fget_cap_locked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp, + struct file **fpp, struct filecaps *havecapsp); +int fget_cap(struct thread *td, int fd, cap_rights_t *needrightsp, + struct file **fpp, struct filecaps *havecapsp); + /* Return a referenced file from an unlocked descriptor. */ int fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp, struct file **fpp, seq_t *seqp); @@ -207,6 +212,18 @@ fget_locked(struct filedesc *fdp, int fd) return (fdp->fd_ofiles[fd].fde_file); } +static __inline struct filedescent * +fdeget_locked(struct filedesc *fdp, int fd) +{ + + FILEDESC_LOCK_ASSERT(fdp); + + if ((u_int)fd > fdp->fd_lastfile) + return (NULL); + + return (&fdp->fd_ofiles[fd]); +} + static __inline bool fd_modified(struct filedesc *fdp, int fd, seq_t seq) { diff --git a/sys/sys/param.h b/sys/sys/param.h index 05f3672..96680f9 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1100509 /* Master, propagated to newvers */ +#define __FreeBSD_version 1100510 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index 3bc2bae..7decd63 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -321,6 +321,7 @@ extern u_long sb_max; extern so_gen_t so_gencnt; struct file; +struct filecaps; struct filedesc; struct mbuf; struct sockaddr; @@ -340,7 +341,7 @@ struct uio; */ int getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len); 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 *havecaps); void soabort(struct socket *so); int soaccept(struct socket *so, struct sockaddr **nam); void soaio_enqueue(struct task *task); -- cgit v1.1