summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2015-08-11 08:43:50 +0000
committerEd Schouten <ed@FreeBSD.org>2015-08-11 08:43:50 +0000
commitaa04a06df55556014e5e6d6e10ce935cda7da6cf (patch)
tree5c95b3e9ef279a86b2e56c1f89deae1119029895
parent812aa46f45a7ae508a72c5484d190b01f6ee8f19 (diff)
Notes
-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 b0b77fe0a9b3..e87f0b1445ac 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 ce68ba80a085..094a32267102 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);