1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-14 10:09:48 +00:00

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
This commit is contained in:
Ed Schouten 2015-08-11 08:43:50 +00:00
parent 812aa46f45
commit aa04a06df5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=286618
2 changed files with 31 additions and 25 deletions

View File

@ -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));
}
/*

View File

@ -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);