svn commit: r307734 - head/sys/kern
Mariusz Zaborski
oshogbo at FreeBSD.org
Fri Oct 21 16:12:25 UTC 2016
Author: oshogbo
Date: Fri Oct 21 16:12:23 2016
New Revision: 307734
URL: https://svnweb.freebsd.org/changeset/base/307734
Log:
capsicum: perform copyout without the fildesc lock held in sys_cap_ioctls_get
Reviewed by: pjd
Modified:
head/sys/kern/sys_capability.c
Modified: head/sys/kern/sys_capability.c
==============================================================================
--- head/sys/kern/sys_capability.c Fri Oct 21 16:12:09 2016 (r307733)
+++ head/sys/kern/sys_capability.c Fri Oct 21 16:12:23 2016 (r307734)
@@ -89,6 +89,8 @@ SYSCTL_INT(_kern, OID_AUTO, trap_enotcap
#ifdef CAPABILITY_MODE
+#define IOCTLS_MAX_COUNT 256 /* XXX: Is 256 sane? */
+
FEATURE(security_capability_mode, "Capsicum Capability Mode");
/*
@@ -398,6 +400,11 @@ kern_cap_ioctls_limit(struct thread *td,
AUDIT_ARG_FD(fd);
+ if (ncmds > IOCTLS_MAX_COUNT) {
+ error = EINVAL;
+ goto out_free;
+ }
+
fdp = td->td_proc->p_fd;
FILEDESC_XLOCK(fdp);
@@ -418,6 +425,7 @@ kern_cap_ioctls_limit(struct thread *td,
error = 0;
out:
FILEDESC_XUNLOCK(fdp);
+out_free:
free(cmds, M_FILECAPS);
return (error);
}
@@ -431,7 +439,7 @@ sys_cap_ioctls_limit(struct thread *td,
ncmds = uap->ncmds;
- if (ncmds > 256) /* XXX: Is 256 sane? */
+ if (ncmds > IOCTLS_MAX_COUNT)
return (EINVAL);
if (ncmds == 0) {
@@ -453,45 +461,59 @@ sys_cap_ioctls_get(struct thread *td, st
{
struct filedesc *fdp;
struct filedescent *fdep;
- u_long *cmds;
- size_t maxcmds;
+ u_long *cmdsp, *dstcmds;
+ size_t maxcmds, ncmds;
+ int16_t count;
int error, fd;
fd = uap->fd;
- cmds = uap->cmds;
+ dstcmds = uap->cmds;
maxcmds = uap->maxcmds;
AUDIT_ARG_FD(fd);
fdp = td->td_proc->p_fd;
- FILEDESC_SLOCK(fdp);
- if (fget_locked(fdp, fd) == NULL) {
+ cmdsp = NULL;
+ if (dstcmds != NULL) {
+ cmdsp = malloc(sizeof(cmdsp[0]) * IOCTLS_MAX_COUNT, M_FILECAPS,
+ M_WAITOK | M_ZERO);
+ }
+
+ FILEDESC_SLOCK(fdp);
+ fdep = fdeget_locked(fdp, fd);
+ if (fdep == NULL) {
error = EBADF;
+ FILEDESC_SUNLOCK(fdp);
goto out;
}
+ count = fdep->fde_nioctls;
+ if (count != -1 && cmdsp != NULL) {
+ ncmds = MIN(count, maxcmds);
+ memcpy(cmdsp, fdep->fde_ioctls, sizeof(cmdsp[0]) * ncmds);
+ }
+ FILEDESC_SUNLOCK(fdp);
/*
* If all ioctls are allowed (fde_nioctls == -1 && fde_ioctls == NULL)
* the only sane thing we can do is to not populate the given array and
* return CAP_IOCTLS_ALL.
*/
-
- fdep = &fdp->fd_ofiles[fd];
- if (cmds != NULL && fdep->fde_ioctls != NULL) {
- error = copyout(fdep->fde_ioctls, cmds,
- sizeof(cmds[0]) * MIN(fdep->fde_nioctls, maxcmds));
- if (error != 0)
- goto out;
- }
- if (fdep->fde_nioctls == -1)
+ if (count != -1) {
+ if (cmdsp != NULL) {
+ error = copyout(cmdsp, dstcmds,
+ sizeof(cmdsp[0]) * ncmds);
+ if (error != 0)
+ goto out;
+ }
+ td->td_retval[0] = count;
+ } else {
td->td_retval[0] = CAP_IOCTLS_ALL;
- else
- td->td_retval[0] = fdep->fde_nioctls;
+ }
error = 0;
out:
- FILEDESC_SUNLOCK(fdp);
+ free(cmdsp, M_FILECAPS);
return (error);
}
More information about the svn-src-head
mailing list