From owner-svn-src-head@FreeBSD.ORG Sun Aug 18 10:30:43 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 0302A27A; Sun, 18 Aug 2013 10:30:43 +0000 (UTC) (envelope-from pjd@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id E390A2A26; Sun, 18 Aug 2013 10:30:42 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r7IAUg8D083240; Sun, 18 Aug 2013 10:30:42 GMT (envelope-from pjd@svn.freebsd.org) Received: (from pjd@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r7IAUfvb083190; Sun, 18 Aug 2013 10:30:41 GMT (envelope-from pjd@svn.freebsd.org) Message-Id: <201308181030.r7IAUfvb083190@svn.freebsd.org> From: Pawel Jakub Dawidek Date: Sun, 18 Aug 2013 10:30:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r254481 - in head/sys: compat/freebsd32 conf kern sys 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.14 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: Sun, 18 Aug 2013 10:30:43 -0000 Author: pjd Date: Sun Aug 18 10:30:41 2013 New Revision: 254481 URL: http://svnweb.freebsd.org/changeset/base/254481 Log: Implement 32bit versions of the cap_ioctls_limit(2) and cap_ioctls_get(2) system calls as unsigned longs have different size on i386 and amd64. Reported by: jilles Sponsored by: The FreeBSD Foundation Added: head/sys/compat/freebsd32/freebsd32_capability.c (contents, props changed) Modified: head/sys/compat/freebsd32/syscalls.master head/sys/conf/files head/sys/kern/sys_capability.c head/sys/sys/syscallsubr.h Added: head/sys/compat/freebsd32/freebsd32_capability.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/compat/freebsd32/freebsd32_capability.c Sun Aug 18 10:30:41 2013 (r254481) @@ -0,0 +1,153 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_capsicum.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#ifdef CAPABILITIES + +MALLOC_DECLARE(M_FILECAPS); + +int +freebsd32_cap_ioctls_limit(struct thread *td, + struct freebsd32_cap_ioctls_limit_args *uap) +{ + u_long *cmds; + uint32_t *cmds32; + size_t ncmds; + u_int i; + int error; + + ncmds = uap->ncmds; + + if (ncmds > 256) /* XXX: Is 256 sane? */ + return (EINVAL); + + if (ncmds == 0) { + cmds = NULL; + } else { + cmds32 = malloc(sizeof(cmds32[0]) * ncmds, M_FILECAPS, M_WAITOK); + error = copyin(uap->cmds, cmds32, sizeof(cmds32[0]) * ncmds); + if (error != 0) { + free(cmds32, M_FILECAPS); + return (error); + } + cmds = malloc(sizeof(cmds[0]) * ncmds, M_FILECAPS, M_WAITOK); + for (i = 0; i < ncmds; i++) + cmds[i] = cmds32[i]; + free(cmds32, M_FILECAPS); + } + + return (kern_cap_ioctls_limit(td, uap->fd, cmds, ncmds)); +} + +int +freebsd32_cap_ioctls_get(struct thread *td, + struct freebsd32_cap_ioctls_get_args *uap) +{ + struct filedesc *fdp; + struct filedescent *fdep; + uint32_t *cmds32; + u_long *cmds; + size_t maxcmds; + int error, fd; + u_int i; + + fd = uap->fd; + cmds32 = uap->cmds; + maxcmds = uap->maxcmds; + + AUDIT_ARG_FD(fd); + + fdp = td->td_proc->p_fd; + FILEDESC_SLOCK(fdp); + + if (fget_locked(fdp, fd) == NULL) { + error = EBADF; + goto out; + } + + /* + * 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 (actually, INT_MAX). + */ + + fdep = &fdp->fd_ofiles[fd]; + cmds = fdep->fde_ioctls; + if (cmds32 != NULL && cmds != NULL) { + for (i = 0; i < MIN(fdep->fde_nioctls, maxcmds); i++) { + error = suword32(&cmds32[i], cmds[i]); + if (error != 0) + goto out; + } + } + if (fdep->fde_nioctls == -1) + td->td_retval[0] = INT_MAX; + else + td->td_retval[0] = fdep->fde_nioctls; + + error = 0; +out: + FILEDESC_SUNLOCK(fdp); + return (error); +} + +#else /* !CAPABILITIES */ + +int +freebsd32_cap_ioctls_limit(struct thread *td, + struct freebsd32_cap_ioctls_limit_args *uap) +{ + + return (ENOSYS); +} + +int +freebsd32_cap_ioctls_get(struct thread *td, + struct freebsd32_cap_ioctls_get_args *uap) +{ + + return (ENOSYS); +} + +#endif /* CAPABILITIES */ Modified: head/sys/compat/freebsd32/syscalls.master ============================================================================== --- head/sys/compat/freebsd32/syscalls.master Sun Aug 18 10:21:29 2013 (r254480) +++ head/sys/compat/freebsd32/syscalls.master Sun Aug 18 10:30:41 2013 (r254481) @@ -1032,10 +1032,12 @@ #endif 533 AUE_CAP_RIGHTS_LIMIT NOPROTO { int cap_rights_limit(int fd, \ uint64_t rights); } -534 AUE_CAP_IOCTLS_LIMIT NOPROTO { int cap_ioctls_limit(int fd, \ - const u_long *cmds, size_t ncmds); } -535 AUE_CAP_IOCTLS_GET NOPROTO { ssize_t cap_ioctls_get(int fd, \ - u_long *cmds, size_t maxcmds); } +534 AUE_CAP_IOCTLS_LIMIT STD { \ + int freebsd32_cap_ioctls_limit(int fd, \ + const uint32_t *cmds, size_t ncmds); } +535 AUE_CAP_IOCTLS_GET STD { \ + ssize_t freebsd32_cap_ioctls_get(int fd, \ + uint32_t *cmds, size_t maxcmds); } 536 AUE_CAP_FCNTLS_LIMIT NOPROTO { int cap_fcntls_limit(int fd, \ uint32_t fcntlrights); } 537 AUE_CAP_FCNTLS_GET NOPROTO { int cap_fcntls_get(int fd, \ Modified: head/sys/conf/files ============================================================================== --- head/sys/conf/files Sun Aug 18 10:21:29 2013 (r254480) +++ head/sys/conf/files Sun Aug 18 10:30:41 2013 (r254481) @@ -275,6 +275,7 @@ cddl/contrib/opensolaris/uts/common/zmod cddl/contrib/opensolaris/uts/common/zmod/zmod.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/zmod_subr.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/zutil.c optional zfs compile-with "${ZFS_C}" +compat/freebsd32/freebsd32_capability.c optional compat_freebsd32 compat/freebsd32/freebsd32_ioctl.c optional compat_freebsd32 compat/freebsd32/freebsd32_misc.c optional compat_freebsd32 compat/freebsd32/freebsd32_syscalls.c optional compat_freebsd32 Modified: head/sys/kern/sys_capability.c ============================================================================== --- head/sys/kern/sys_capability.c Sun Aug 18 10:21:29 2013 (r254480) +++ head/sys/kern/sys_capability.c Sun Aug 18 10:30:41 2013 (r254481) @@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -328,32 +329,14 @@ cap_ioctl_limit_check(struct filedesc *f } int -sys_cap_ioctls_limit(struct thread *td, struct cap_ioctls_limit_args *uap) +kern_cap_ioctls_limit(struct thread *td, int fd, u_long *cmds, size_t ncmds) { struct filedesc *fdp; - u_long *cmds, *ocmds; - size_t ncmds; - int error, fd; - - fd = uap->fd; - ncmds = uap->ncmds; + u_long *ocmds; + int error; AUDIT_ARG_FD(fd); - if (ncmds > 256) /* XXX: Is 256 sane? */ - return (EINVAL); - - if (ncmds == 0) { - cmds = NULL; - } else { - cmds = malloc(sizeof(cmds[0]) * ncmds, M_FILECAPS, M_WAITOK); - error = copyin(uap->cmds, cmds, sizeof(cmds[0]) * ncmds); - if (error != 0) { - free(cmds, M_FILECAPS); - return (error); - } - } - fdp = td->td_proc->p_fd; FILEDESC_XLOCK(fdp); @@ -379,6 +362,32 @@ out: } int +sys_cap_ioctls_limit(struct thread *td, struct cap_ioctls_limit_args *uap) +{ + u_long *cmds; + size_t ncmds; + int error; + + ncmds = uap->ncmds; + + if (ncmds > 256) /* XXX: Is 256 sane? */ + return (EINVAL); + + if (ncmds == 0) { + cmds = NULL; + } else { + cmds = malloc(sizeof(cmds[0]) * ncmds, M_FILECAPS, M_WAITOK); + error = copyin(uap->cmds, cmds, sizeof(cmds[0]) * ncmds); + if (error != 0) { + free(cmds, M_FILECAPS); + return (error); + } + } + + return (kern_cap_ioctls_limit(td, uap->fd, cmds, ncmds)); +} + +int sys_cap_ioctls_get(struct thread *td, struct cap_ioctls_get_args *uap) { struct filedesc *fdp; Modified: head/sys/sys/syscallsubr.h ============================================================================== --- head/sys/sys/syscallsubr.h Sun Aug 18 10:21:29 2013 (r254480) +++ head/sys/sys/syscallsubr.h Sun Aug 18 10:30:41 2013 (r254481) @@ -71,6 +71,8 @@ int kern_adjtime(struct thread *td, stru int kern_alternate_path(struct thread *td, const char *prefix, const char *path, enum uio_seg pathseg, char **pathbuf, int create, int dirfd); int kern_bind(struct thread *td, int fd, struct sockaddr *sa); +int kern_cap_ioctls_limit(struct thread *td, int fd, u_long *cmds, + size_t ncmds); int kern_chdir(struct thread *td, char *path, enum uio_seg pathseg); int kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, int mode);