Use the fdeget_locked function instead of the fget_locked in the
sys_capability. Reviewed by: pjd@ (earlier version) Discussed with: mjg@
This commit is contained in:
parent
ead15282ae
commit
20641651ec
@ -205,10 +205,10 @@ cap_rights_to_vmprot(cap_rights_t *havep)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
cap_rights_t *
|
cap_rights_t *
|
||||||
cap_rights_fde(struct filedescent *fde)
|
cap_rights_fde(struct filedescent *fdep)
|
||||||
{
|
{
|
||||||
|
|
||||||
return (&fde->fde_rights);
|
return (&fdep->fde_rights);
|
||||||
}
|
}
|
||||||
|
|
||||||
cap_rights_t *
|
cap_rights_t *
|
||||||
@ -222,24 +222,26 @@ int
|
|||||||
kern_cap_rights_limit(struct thread *td, int fd, cap_rights_t *rights)
|
kern_cap_rights_limit(struct thread *td, int fd, cap_rights_t *rights)
|
||||||
{
|
{
|
||||||
struct filedesc *fdp;
|
struct filedesc *fdp;
|
||||||
|
struct filedescent *fdep;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
fdp = td->td_proc->p_fd;
|
fdp = td->td_proc->p_fd;
|
||||||
FILEDESC_XLOCK(fdp);
|
FILEDESC_XLOCK(fdp);
|
||||||
if (fget_locked(fdp, fd) == NULL) {
|
fdep = fdeget_locked(fdp, fd);
|
||||||
|
if (fdep == NULL) {
|
||||||
FILEDESC_XUNLOCK(fdp);
|
FILEDESC_XUNLOCK(fdp);
|
||||||
return (EBADF);
|
return (EBADF);
|
||||||
}
|
}
|
||||||
error = _cap_check(cap_rights(fdp, fd), rights, CAPFAIL_INCREASE);
|
error = _cap_check(cap_rights(fdp, fd), rights, CAPFAIL_INCREASE);
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
fdp->fd_ofiles[fd].fde_rights = *rights;
|
fdep->fde_rights = *rights;
|
||||||
if (!cap_rights_is_set(rights, CAP_IOCTL)) {
|
if (!cap_rights_is_set(rights, CAP_IOCTL)) {
|
||||||
free(fdp->fd_ofiles[fd].fde_ioctls, M_FILECAPS);
|
free(fdep->fde_ioctls, M_FILECAPS);
|
||||||
fdp->fd_ofiles[fd].fde_ioctls = NULL;
|
fdep->fde_ioctls = NULL;
|
||||||
fdp->fd_ofiles[fd].fde_nioctls = 0;
|
fdep->fde_nioctls = 0;
|
||||||
}
|
}
|
||||||
if (!cap_rights_is_set(rights, CAP_FCNTL))
|
if (!cap_rights_is_set(rights, CAP_FCNTL))
|
||||||
fdp->fd_ofiles[fd].fde_fcntls = 0;
|
fdep->fde_fcntls = 0;
|
||||||
}
|
}
|
||||||
FILEDESC_XUNLOCK(fdp);
|
FILEDESC_XUNLOCK(fdp);
|
||||||
return (error);
|
return (error);
|
||||||
@ -341,19 +343,23 @@ sys___cap_rights_get(struct thread *td, struct __cap_rights_get_args *uap)
|
|||||||
int
|
int
|
||||||
cap_ioctl_check(struct filedesc *fdp, int fd, u_long cmd)
|
cap_ioctl_check(struct filedesc *fdp, int fd, u_long cmd)
|
||||||
{
|
{
|
||||||
|
struct filedescent *fdep;
|
||||||
u_long *cmds;
|
u_long *cmds;
|
||||||
ssize_t ncmds;
|
ssize_t ncmds;
|
||||||
long i;
|
long i;
|
||||||
|
|
||||||
FILEDESC_LOCK_ASSERT(fdp);
|
|
||||||
KASSERT(fd >= 0 && fd < fdp->fd_nfiles,
|
KASSERT(fd >= 0 && fd < fdp->fd_nfiles,
|
||||||
|
("%s: invalid fd=%d", __func__, fd));
|
||||||
|
|
||||||
|
fdep = fdeget_locked(fdp, fd);
|
||||||
|
KASSERT(fdep == NULL,
|
||||||
("%s: invalid fd=%d", __func__, fd));
|
("%s: invalid fd=%d", __func__, fd));
|
||||||
|
|
||||||
ncmds = fdp->fd_ofiles[fd].fde_nioctls;
|
ncmds = fdep->fde_nioctls;
|
||||||
if (ncmds == -1)
|
if (ncmds == -1)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
cmds = fdp->fd_ofiles[fd].fde_ioctls;
|
cmds = fdep->fde_ioctls;
|
||||||
for (i = 0; i < ncmds; i++) {
|
for (i = 0; i < ncmds; i++) {
|
||||||
if (cmds[i] == cmd)
|
if (cmds[i] == cmd)
|
||||||
return (0);
|
return (0);
|
||||||
@ -366,7 +372,7 @@ cap_ioctl_check(struct filedesc *fdp, int fd, u_long cmd)
|
|||||||
* Check if the current ioctls list can be replaced by the new one.
|
* Check if the current ioctls list can be replaced by the new one.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
cap_ioctl_limit_check(struct filedesc *fdp, int fd, const u_long *cmds,
|
cap_ioctl_limit_check(struct filedescent *fdep, const u_long *cmds,
|
||||||
size_t ncmds)
|
size_t ncmds)
|
||||||
{
|
{
|
||||||
u_long *ocmds;
|
u_long *ocmds;
|
||||||
@ -374,13 +380,13 @@ cap_ioctl_limit_check(struct filedesc *fdp, int fd, const u_long *cmds,
|
|||||||
u_long i;
|
u_long i;
|
||||||
long j;
|
long j;
|
||||||
|
|
||||||
oncmds = fdp->fd_ofiles[fd].fde_nioctls;
|
oncmds = fdep->fde_nioctls;
|
||||||
if (oncmds == -1)
|
if (oncmds == -1)
|
||||||
return (0);
|
return (0);
|
||||||
if (oncmds < (ssize_t)ncmds)
|
if (oncmds < (ssize_t)ncmds)
|
||||||
return (ENOTCAPABLE);
|
return (ENOTCAPABLE);
|
||||||
|
|
||||||
ocmds = fdp->fd_ofiles[fd].fde_ioctls;
|
ocmds = fdep->fde_ioctls;
|
||||||
for (i = 0; i < ncmds; i++) {
|
for (i = 0; i < ncmds; i++) {
|
||||||
for (j = 0; j < oncmds; j++) {
|
for (j = 0; j < oncmds; j++) {
|
||||||
if (cmds[i] == ocmds[j])
|
if (cmds[i] == ocmds[j])
|
||||||
@ -397,6 +403,7 @@ int
|
|||||||
kern_cap_ioctls_limit(struct thread *td, int fd, u_long *cmds, size_t ncmds)
|
kern_cap_ioctls_limit(struct thread *td, int fd, u_long *cmds, size_t ncmds)
|
||||||
{
|
{
|
||||||
struct filedesc *fdp;
|
struct filedesc *fdp;
|
||||||
|
struct filedescent *fdep;
|
||||||
u_long *ocmds;
|
u_long *ocmds;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@ -410,18 +417,19 @@ kern_cap_ioctls_limit(struct thread *td, int fd, u_long *cmds, size_t ncmds)
|
|||||||
fdp = td->td_proc->p_fd;
|
fdp = td->td_proc->p_fd;
|
||||||
FILEDESC_XLOCK(fdp);
|
FILEDESC_XLOCK(fdp);
|
||||||
|
|
||||||
if (fget_locked(fdp, fd) == NULL) {
|
fdep = fdeget_locked(fdp, fd);
|
||||||
|
if (fdep == NULL) {
|
||||||
error = EBADF;
|
error = EBADF;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = cap_ioctl_limit_check(fdp, fd, cmds, ncmds);
|
error = cap_ioctl_limit_check(fdep, cmds, ncmds);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ocmds = fdp->fd_ofiles[fd].fde_ioctls;
|
ocmds = fdep->fde_ioctls;
|
||||||
fdp->fd_ofiles[fd].fde_ioctls = cmds;
|
fdep->fde_ioctls = cmds;
|
||||||
fdp->fd_ofiles[fd].fde_nioctls = ncmds;
|
fdep->fde_nioctls = ncmds;
|
||||||
|
|
||||||
cmds = ocmds;
|
cmds = ocmds;
|
||||||
error = 0;
|
error = 0;
|
||||||
@ -523,7 +531,7 @@ out:
|
|||||||
* Test whether a capability grants the given fcntl command.
|
* Test whether a capability grants the given fcntl command.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
cap_fcntl_check_fde(struct filedescent *fde, int cmd)
|
cap_fcntl_check_fde(struct filedescent *fdep, int cmd)
|
||||||
{
|
{
|
||||||
uint32_t fcntlcap;
|
uint32_t fcntlcap;
|
||||||
|
|
||||||
@ -531,7 +539,7 @@ cap_fcntl_check_fde(struct filedescent *fde, int cmd)
|
|||||||
KASSERT((CAP_FCNTL_ALL & fcntlcap) != 0,
|
KASSERT((CAP_FCNTL_ALL & fcntlcap) != 0,
|
||||||
("Unsupported fcntl=%d.", cmd));
|
("Unsupported fcntl=%d.", cmd));
|
||||||
|
|
||||||
if ((fde->fde_fcntls & fcntlcap) != 0)
|
if ((fdep->fde_fcntls & fcntlcap) != 0)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
return (ENOTCAPABLE);
|
return (ENOTCAPABLE);
|
||||||
@ -551,6 +559,7 @@ int
|
|||||||
sys_cap_fcntls_limit(struct thread *td, struct cap_fcntls_limit_args *uap)
|
sys_cap_fcntls_limit(struct thread *td, struct cap_fcntls_limit_args *uap)
|
||||||
{
|
{
|
||||||
struct filedesc *fdp;
|
struct filedesc *fdp;
|
||||||
|
struct filedescent *fdep;
|
||||||
uint32_t fcntlrights;
|
uint32_t fcntlrights;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@ -566,17 +575,18 @@ sys_cap_fcntls_limit(struct thread *td, struct cap_fcntls_limit_args *uap)
|
|||||||
fdp = td->td_proc->p_fd;
|
fdp = td->td_proc->p_fd;
|
||||||
FILEDESC_XLOCK(fdp);
|
FILEDESC_XLOCK(fdp);
|
||||||
|
|
||||||
if (fget_locked(fdp, fd) == NULL) {
|
fdep = fdeget_locked(fdp, fd);
|
||||||
|
if (fdep == NULL) {
|
||||||
FILEDESC_XUNLOCK(fdp);
|
FILEDESC_XUNLOCK(fdp);
|
||||||
return (EBADF);
|
return (EBADF);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fcntlrights & ~fdp->fd_ofiles[fd].fde_fcntls) != 0) {
|
if ((fcntlrights & ~fdep->fde_fcntls) != 0) {
|
||||||
FILEDESC_XUNLOCK(fdp);
|
FILEDESC_XUNLOCK(fdp);
|
||||||
return (ENOTCAPABLE);
|
return (ENOTCAPABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
fdp->fd_ofiles[fd].fde_fcntls = fcntlrights;
|
fdep->fde_fcntls = fcntlrights;
|
||||||
FILEDESC_XUNLOCK(fdp);
|
FILEDESC_XUNLOCK(fdp);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
@ -586,6 +596,7 @@ int
|
|||||||
sys_cap_fcntls_get(struct thread *td, struct cap_fcntls_get_args *uap)
|
sys_cap_fcntls_get(struct thread *td, struct cap_fcntls_get_args *uap)
|
||||||
{
|
{
|
||||||
struct filedesc *fdp;
|
struct filedesc *fdp;
|
||||||
|
struct filedescent *fdep;
|
||||||
uint32_t rights;
|
uint32_t rights;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@ -595,11 +606,12 @@ sys_cap_fcntls_get(struct thread *td, struct cap_fcntls_get_args *uap)
|
|||||||
|
|
||||||
fdp = td->td_proc->p_fd;
|
fdp = td->td_proc->p_fd;
|
||||||
FILEDESC_SLOCK(fdp);
|
FILEDESC_SLOCK(fdp);
|
||||||
if (fget_locked(fdp, fd) == NULL) {
|
fdep = fdeget_locked(fdp, fd);
|
||||||
|
if (fdep == NULL) {
|
||||||
FILEDESC_SUNLOCK(fdp);
|
FILEDESC_SUNLOCK(fdp);
|
||||||
return (EBADF);
|
return (EBADF);
|
||||||
}
|
}
|
||||||
rights = fdp->fd_ofiles[fd].fde_fcntls;
|
rights = fdep->fde_fcntls;
|
||||||
FILEDESC_SUNLOCK(fdp);
|
FILEDESC_SUNLOCK(fdp);
|
||||||
|
|
||||||
return (copyout(&rights, uap->fcntlrightsp, sizeof(rights)));
|
return (copyout(&rights, uap->fcntlrightsp, sizeof(rights)));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user