Handle cases where capability rights are not provided.
Reported by: kib
This commit is contained in:
parent
12cfeea19a
commit
1c7defb76e
@ -54,7 +54,7 @@ releasef(int fd)
|
|||||||
struct file *fp;
|
struct file *fp;
|
||||||
|
|
||||||
/* No CAP_ rights required, as we're only releasing. */
|
/* No CAP_ rights required, as we're only releasing. */
|
||||||
if (fget(curthread, fd, 0, &fp) == 0) {
|
if (fget(curthread, fd, NULL, &fp) == 0) {
|
||||||
fdrop(fp, curthread);
|
fdrop(fp, curthread);
|
||||||
fdrop(fp, curthread);
|
fdrop(fp, curthread);
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,9 @@ __FBSDID("$FreeBSD$");
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#if __FreeBSD_version >= 900000
|
||||||
|
#include <sys/capability.h>
|
||||||
|
#endif
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/conf.h>
|
#include <sys/conf.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
@ -77,15 +80,19 @@ static int
|
|||||||
aacraid_linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
|
aacraid_linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
|
||||||
{
|
{
|
||||||
struct file *fp;
|
struct file *fp;
|
||||||
|
#if __FreeBSD_version >= 900000
|
||||||
|
cap_rights_t rights;
|
||||||
|
#endif
|
||||||
u_long cmd;
|
u_long cmd;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
if ((error = fget(td, args->fd,
|
||||||
#if __FreeBSD_version >= 900000
|
#if __FreeBSD_version >= 900000
|
||||||
if ((error = fget(td, args->fd, 0, &fp)) != 0)
|
cap_rights_init(&rights, CAP_IOCTL),
|
||||||
#else
|
|
||||||
if ((error = fget(td, args->fd, &fp)) != 0)
|
|
||||||
#endif
|
#endif
|
||||||
|
&fp)) != 0) {
|
||||||
return (error);
|
return (error);
|
||||||
|
}
|
||||||
cmd = args->cmd;
|
cmd = args->cmd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -309,7 +309,7 @@ fdesc_lookup(ap)
|
|||||||
/*
|
/*
|
||||||
* No rights to check since 'fp' isn't actually used.
|
* No rights to check since 'fp' isn't actually used.
|
||||||
*/
|
*/
|
||||||
if ((error = fget(td, fd, 0, &fp)) != 0)
|
if ((error = fget(td, fd, NULL, &fp)) != 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
/* Check if we're looking up ourselves. */
|
/* Check if we're looking up ourselves. */
|
||||||
|
@ -586,8 +586,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
|
|||||||
|
|
||||||
case F_SETLK:
|
case F_SETLK:
|
||||||
do_setlk:
|
do_setlk:
|
||||||
error = fget_unlocked(fdp, fd,
|
cap_rights_init(&rights, CAP_FLOCK);
|
||||||
cap_rights_init(&rights, CAP_FLOCK), 0, &fp, NULL);
|
error = fget_unlocked(fdp, fd, &rights, 0, &fp, NULL);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
break;
|
break;
|
||||||
if (fp->f_type != DTYPE_VNODE) {
|
if (fp->f_type != DTYPE_VNODE) {
|
||||||
@ -676,7 +676,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
|
|||||||
* that the closing thread was a bit slower and that the
|
* that the closing thread was a bit slower and that the
|
||||||
* advisory lock succeeded before the close.
|
* advisory lock succeeded before the close.
|
||||||
*/
|
*/
|
||||||
error = fget_unlocked(fdp, fd, 0, 0, &fp2, NULL);
|
error = fget_unlocked(fdp, fd, &rights, 0, &fp2, NULL);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
fdrop(fp, td);
|
fdrop(fp, td);
|
||||||
break;
|
break;
|
||||||
@ -733,7 +733,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
|
|||||||
arg = arg ? 128 * 1024: 0;
|
arg = arg ? 128 * 1024: 0;
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case F_READAHEAD:
|
case F_READAHEAD:
|
||||||
error = fget_unlocked(fdp, fd, 0, 0, &fp, NULL);
|
error = fget_unlocked(fdp, fd, NULL, 0, &fp, NULL);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
break;
|
break;
|
||||||
if (fp->f_type != DTYPE_VNODE) {
|
if (fp->f_type != DTYPE_VNODE) {
|
||||||
@ -2324,13 +2324,15 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
|
|||||||
return (EBADF);
|
return (EBADF);
|
||||||
#ifdef CAPABILITIES
|
#ifdef CAPABILITIES
|
||||||
haverights = *cap_rights(fdp, fd);
|
haverights = *cap_rights(fdp, fd);
|
||||||
error = cap_check(&haverights, needrightsp);
|
if (needrightsp != NULL) {
|
||||||
if (error != 0)
|
error = cap_check(&haverights, needrightsp);
|
||||||
return (error);
|
|
||||||
if (cap_rights_is_set(needrightsp, CAP_FCNTL)) {
|
|
||||||
error = cap_fcntl_check(fdp, fd, needfcntl);
|
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
|
if (cap_rights_is_set(needrightsp, CAP_FCNTL)) {
|
||||||
|
error = cap_fcntl_check(fdp, fd, needfcntl);
|
||||||
|
if (error != 0)
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
count = fp->f_count;
|
count = fp->f_count;
|
||||||
@ -2382,7 +2384,10 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags,
|
|||||||
*fpp = NULL;
|
*fpp = NULL;
|
||||||
if (td == NULL || (fdp = td->td_proc->p_fd) == NULL)
|
if (td == NULL || (fdp = td->td_proc->p_fd) == NULL)
|
||||||
return (EBADF);
|
return (EBADF);
|
||||||
needrights = *needrightsp;
|
if (needrightsp != NULL)
|
||||||
|
needrights = *needrightsp;
|
||||||
|
else
|
||||||
|
cap_rights_init(&needrights);
|
||||||
if (maxprotp != NULL)
|
if (maxprotp != NULL)
|
||||||
cap_rights_set(&needrights, CAP_MMAP);
|
cap_rights_set(&needrights, CAP_MMAP);
|
||||||
error = fget_unlocked(fdp, fd, &needrights, 0, &fp, &haverights);
|
error = fget_unlocked(fdp, fd, &needrights, 0, &fp, &haverights);
|
||||||
@ -2517,9 +2522,11 @@ fgetvp_rights(struct thread *td, int fd, cap_rights_t *needrightsp,
|
|||||||
return (EBADF);
|
return (EBADF);
|
||||||
|
|
||||||
#ifdef CAPABILITIES
|
#ifdef CAPABILITIES
|
||||||
error = cap_check(cap_rights(fdp, fd), needrightsp);
|
if (needrightsp != NULL) {
|
||||||
if (error != 0)
|
error = cap_check(cap_rights(fdp, fd), needrightsp);
|
||||||
return (error);
|
if (error != 0)
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fp->f_vnode == NULL)
|
if (fp->f_vnode == NULL)
|
||||||
|
@ -47,8 +47,10 @@ linux_fget(unsigned int fd)
|
|||||||
{
|
{
|
||||||
struct file *file;
|
struct file *file;
|
||||||
|
|
||||||
if (fget_unlocked(curthread->td_proc->p_fd, fd, 0, 0, &file, NULL) != 0)
|
if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, 0, &file,
|
||||||
|
NULL) != 0) {
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
}
|
||||||
return (struct linux_file *)file->f_data;
|
return (struct linux_file *)file->f_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,8 +72,10 @@ put_unused_fd(unsigned int fd)
|
|||||||
{
|
{
|
||||||
struct file *file;
|
struct file *file;
|
||||||
|
|
||||||
if (fget_unlocked(curthread->td_proc->p_fd, fd, 0, 0, &file, NULL) != 0)
|
if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, 0, &file,
|
||||||
|
NULL) != 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
fdclose(curthread->td_proc->p_fd, file, fd, curthread);
|
fdclose(curthread->td_proc->p_fd, file, fd, curthread);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,8 +84,10 @@ fd_install(unsigned int fd, struct linux_file *filp)
|
|||||||
{
|
{
|
||||||
struct file *file;
|
struct file *file;
|
||||||
|
|
||||||
if (fget_unlocked(curthread->td_proc->p_fd, fd, 0, 0, &file, NULL) != 0)
|
if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, 0, &file,
|
||||||
|
NULL) != 0) {
|
||||||
file = NULL;
|
file = NULL;
|
||||||
|
}
|
||||||
filp->_file = file;
|
filp->_file = file;
|
||||||
finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops);
|
finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops);
|
||||||
}
|
}
|
||||||
|
@ -496,7 +496,7 @@ audit_canon_path(struct thread *td, int dirfd, char *path, char *cpath)
|
|||||||
vhold(cvnp);
|
vhold(cvnp);
|
||||||
} else {
|
} else {
|
||||||
/* XXX: fgetvp() that vhold()s vnode instead of vref()ing it would be better */
|
/* XXX: fgetvp() that vhold()s vnode instead of vref()ing it would be better */
|
||||||
error = fgetvp(td, dirfd, 0, &cvnp);
|
error = fgetvp(td, dirfd, NULL, &cvnp);
|
||||||
if (error) {
|
if (error) {
|
||||||
cpath[0] = '\0';
|
cpath[0] = '\0';
|
||||||
if (rvnp != NULL)
|
if (rvnp != NULL)
|
||||||
|
Loading…
Reference in New Issue
Block a user