From owner-svn-src-head@freebsd.org Fri Oct 21 16:12:25 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 52935C1C302; Fri, 21 Oct 2016 16:12:25 +0000 (UTC) (envelope-from oshogbo@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 131EFD4A; Fri, 21 Oct 2016 16:12:25 +0000 (UTC) (envelope-from oshogbo@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9LGCOBd059471; Fri, 21 Oct 2016 16:12:24 GMT (envelope-from oshogbo@FreeBSD.org) Received: (from oshogbo@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9LGCOv4059470; Fri, 21 Oct 2016 16:12:24 GMT (envelope-from oshogbo@FreeBSD.org) Message-Id: <201610211612.u9LGCOv4059470@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: oshogbo set sender to oshogbo@FreeBSD.org using -f From: Mariusz Zaborski Date: Fri, 21 Oct 2016 16:12:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r307734 - head/sys/kern X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Oct 2016 16:12:25 -0000 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); }