svn commit: r286618 - in head/sys: kern sys
Ed Schouten
ed at FreeBSD.org
Tue Aug 11 08:43:51 UTC 2015
Author: ed
Date: Tue Aug 11 08:43:50 2015
New Revision: 286618
URL: https://svnweb.freebsd.org/changeset/base/286618
Log:
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
Modified:
head/sys/kern/sys_capability.c
head/sys/sys/syscallsubr.h
Modified: head/sys/kern/sys_capability.c
==============================================================================
--- head/sys/kern/sys_capability.c Tue Aug 11 05:58:33 2015 (r286617)
+++ head/sys/kern/sys_capability.c Tue Aug 11 08:43:50 2015 (r286618)
@@ -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,
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));
}
/*
Modified: head/sys/sys/syscallsubr.h
==============================================================================
--- head/sys/sys/syscallsubr.h Tue Aug 11 05:58:33 2015 (r286617)
+++ head/sys/sys/syscallsubr.h Tue Aug 11 08:43:50 2015 (r286618)
@@ -74,6 +74,7 @@ int kern_alternate_path(struct thread *t
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);
More information about the svn-src-all
mailing list