summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2015-08-11 08:43:50 +0000
committered <ed@FreeBSD.org>2015-08-11 08:43:50 +0000
commit8fba8d3894b0df35e793695331271458e1478729 (patch)
tree5c95b3e9ef279a86b2e56c1f89deae1119029895 /sys
parent5b86b1c65a4a5e8eb458221a44ac021a802207d3 (diff)
downloadFreeBSD-src-8fba8d3894b0df35e793695331271458e1478729.zip
FreeBSD-src-8fba8d3894b0df35e793695331271458e1478729.tar.gz
Introduce kern_cap_rights_limit().
The existing sys_cap_rights_limit() expects that a cap_rights_t object lives in userspace. It is therefore hard to call into it from kernelspace. Move the interesting bits of sys_cap_rights_limit() into kern_cap_rights_limit(), so that we can call into it from the CloudABI compatibility layer. Obtained from: https://github.com/NuxiNL/freebsd Differential Revision: https://reviews.freebsd.org/D3314
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/sys_capability.c55
-rw-r--r--sys/sys/syscallsubr.h1
2 files changed, 31 insertions, 25 deletions
diff --git a/sys/kern/sys_capability.c b/sys/kern/sys_capability.c
index b0b77fe..e87f0b1 100644
--- a/sys/kern/sys_capability.c
+++ b/sys/kern/sys_capability.c
@@ -213,15 +213,41 @@ cap_rights(struct filedesc *fdp, int fd)
return (cap_rights_fde(&fdp->fd_ofiles[fd]));
}
+int
+kern_cap_rights_limit(struct thread *td, int fd, cap_rights_t *rights)
+{
+ struct filedesc *fdp;
+ int error;
+
+ fdp = td->td_proc->p_fd;
+ FILEDESC_XLOCK(fdp);
+ if (fget_locked(fdp, fd) == NULL) {
+ FILEDESC_XUNLOCK(fdp);
+ return (EBADF);
+ }
+ error = _cap_check(cap_rights(fdp, fd), rights, CAPFAIL_INCREASE);
+ if (error == 0) {
+ fdp->fd_ofiles[fd].fde_rights = *rights;
+ if (!cap_rights_is_set(rights, CAP_IOCTL)) {
+ free(fdp->fd_ofiles[fd].fde_ioctls, M_FILECAPS);
+ fdp->fd_ofiles[fd].fde_ioctls = NULL;
+ fdp->fd_ofiles[fd].fde_nioctls = 0;
+ }
+ if (!cap_rights_is_set(rights, CAP_FCNTL))
+ fdp->fd_ofiles[fd].fde_fcntls = 0;
+ }
+ FILEDESC_XUNLOCK(fdp);
+ return (error);
+}
+
/*
* System call to limit rights of the given capability.
*/
int
sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap)
{
- struct filedesc *fdp;
cap_rights_t rights;
- int error, fd, version;
+ int error, version;
cap_rights_init(&rights);
@@ -252,30 +278,9 @@ sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap)
ktrcaprights(&rights);
#endif
- fd = uap->fd;
-
- AUDIT_ARG_FD(fd);
+ AUDIT_ARG_FD(uap->fd);
AUDIT_ARG_RIGHTS(&rights);
-
- fdp = td->td_proc->p_fd;
- FILEDESC_XLOCK(fdp);
- if (fget_locked(fdp, fd) == NULL) {
- FILEDESC_XUNLOCK(fdp);
- return (EBADF);
- }
- error = _cap_check(cap_rights(fdp, fd), &rights, CAPFAIL_INCREASE);
- if (error == 0) {
- fdp->fd_ofiles[fd].fde_rights = rights;
- if (!cap_rights_is_set(&rights, CAP_IOCTL)) {
- free(fdp->fd_ofiles[fd].fde_ioctls, M_FILECAPS);
- fdp->fd_ofiles[fd].fde_ioctls = NULL;
- fdp->fd_ofiles[fd].fde_nioctls = 0;
- }
- if (!cap_rights_is_set(&rights, CAP_FCNTL))
- fdp->fd_ofiles[fd].fde_fcntls = 0;
- }
- FILEDESC_XUNLOCK(fdp);
- return (error);
+ return (kern_cap_rights_limit(td, uap->fd, &rights));
}
/*
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index ce68ba8..094a322 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -74,6 +74,7 @@ int kern_alternate_path(struct thread *td, const char *prefix, const char *path,
int kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa);
int kern_cap_ioctls_limit(struct thread *td, int fd, u_long *cmds,
size_t ncmds);
+int kern_cap_rights_limit(struct thread *td, int fd, cap_rights_t *rights);
int kern_chdir(struct thread *td, char *path, enum uio_seg pathseg);
int kern_clock_getcpuclockid2(struct thread *td, id_t id, int which,
clockid_t *clk_id);
OpenPOWER on IntegriCloud