summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordchagin <dchagin@FreeBSD.org>2017-03-15 16:38:39 +0000
committerdchagin <dchagin@FreeBSD.org>2017-03-15 16:38:39 +0000
commitb8129eaf84f85d9a5cbdc81025dd8314f8148d85 (patch)
treee6c7c72459a687709a96584c6b3673bca57d7a92 /sys
parent466bdf25f48f01fdeff163183f0be4fa531d8545 (diff)
downloadFreeBSD-src-b8129eaf84f85d9a5cbdc81025dd8314f8148d85.zip
FreeBSD-src-b8129eaf84f85d9a5cbdc81025dd8314f8148d85.tar.gz
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.
Diffstat (limited to 'sys')
-rw-r--r--sys/compat/cloudabi/cloudabi_sock.c2
-rw-r--r--sys/compat/linux/linux_socket.c34
-rw-r--r--sys/dev/iscsi_initiator/isc_soc.c1
-rw-r--r--sys/dev/iscsi_initiator/iscsi.c16
-rw-r--r--sys/kern/kern_descrip.c185
-rw-r--r--sys/kern/kern_sendfile.c2
-rw-r--r--sys/kern/uipc_syscalls.c35
-rw-r--r--sys/netinet/sctp_syscalls.c15
-rw-r--r--sys/sys/file.h6
-rw-r--r--sys/sys/filedesc.h17
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/socketvar.h3
12 files changed, 175 insertions, 143 deletions
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 <sys/resourcevar.h>
#include <sys/sbuf.h>
#include <sys/signalvar.h>
-#include <sys/socketvar.h>
#include <sys/kdb.h>
#include <sys/stat.h>
#include <sys/sx.h>
@@ -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);
OpenPOWER on IntegriCloud