From owner-svn-src-head@freebsd.org Tue Jun 19 21:26:24 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id DDF7B100FB60; Tue, 19 Jun 2018 21:26:23 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 90B1176C85; Tue, 19 Jun 2018 21:26:23 +0000 (UTC) (envelope-from emaste@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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 7195A19203; Tue, 19 Jun 2018 21:26:23 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w5JLQNms036413; Tue, 19 Jun 2018 21:26:23 GMT (envelope-from emaste@FreeBSD.org) Received: (from emaste@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w5JLQNB9036412; Tue, 19 Jun 2018 21:26:23 GMT (envelope-from emaste@FreeBSD.org) Message-Id: <201806192126.w5JLQNB9036412@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: emaste set sender to emaste@FreeBSD.org using -f From: Ed Maste Date: Tue, 19 Jun 2018 21:26:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r335387 - head/sys/compat/linux X-SVN-Group: head X-SVN-Commit-Author: emaste X-SVN-Commit-Paths: head/sys/compat/linux X-SVN-Commit-Revision: 335387 X-SVN-Commit-Repository: base 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.26 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: Tue, 19 Jun 2018 21:26:24 -0000 Author: emaste Date: Tue Jun 19 21:26:23 2018 New Revision: 335387 URL: https://svnweb.freebsd.org/changeset/base/335387 Log: linuxulator: handle V3 capget/capset Linux 2.6.26 introduced 64-bit capability sets. Extend our stub implementation to handle both 32- and 64-bit. (We still report no capabilities in capget, and disallow any in capset.) Reviewed by: chuck Sponsored by: Turing Robotic Industries Inc. Differential Revision: https://reviews.freebsd.org/D15887 Modified: head/sys/compat/linux/linux_misc.c Modified: head/sys/compat/linux/linux_misc.c ============================================================================== --- head/sys/compat/linux/linux_misc.c Tue Jun 19 21:07:25 2018 (r335386) +++ head/sys/compat/linux/linux_misc.c Tue Jun 19 21:26:23 2018 (r335387) @@ -1867,7 +1867,9 @@ linux_exit_group(struct thread *td, struct linux_exit_ /* NOTREACHED */ } -#define _LINUX_CAPABILITY_VERSION 0x19980330 +#define _LINUX_CAPABILITY_VERSION_1 0x19980330 +#define _LINUX_CAPABILITY_VERSION_2 0x20071026 +#define _LINUX_CAPABILITY_VERSION_3 0x20080522 struct l_user_cap_header { l_int version; @@ -1881,27 +1883,35 @@ struct l_user_cap_data { }; int -linux_capget(struct thread *td, struct linux_capget_args *args) +linux_capget(struct thread *td, struct linux_capget_args *uap) { struct l_user_cap_header luch; - struct l_user_cap_data lucd; - int error; + struct l_user_cap_data lucd[2]; + int error, u32s; - if (args->hdrp == NULL) + if (uap->hdrp == NULL) return (EFAULT); - error = copyin(args->hdrp, &luch, sizeof(luch)); + error = copyin(uap->hdrp, &luch, sizeof(luch)); if (error != 0) return (error); - if (luch.version != _LINUX_CAPABILITY_VERSION) { + switch (luch.version) { + case _LINUX_CAPABILITY_VERSION_1: + u32s = 1; + break; + case _LINUX_CAPABILITY_VERSION_2: + case _LINUX_CAPABILITY_VERSION_3: + u32s = 2; + break; + default: #ifdef DEBUG if (ldebug(capget)) printf(LMSG("invalid capget capability version 0x%x"), luch.version); #endif - luch.version = _LINUX_CAPABILITY_VERSION; - error = copyout(&luch, args->hdrp, sizeof(luch)); + luch.version = _LINUX_CAPABILITY_VERSION_1; + error = copyout(&luch, uap->hdrp, sizeof(luch)); if (error) return (error); return (EINVAL); @@ -1910,42 +1920,50 @@ linux_capget(struct thread *td, struct linux_capget_ar if (luch.pid) return (EPERM); - if (args->datap) { + if (uap->datap) { /* * The current implementation doesn't support setting * a capability (it's essentially a stub) so indicate * that no capabilities are currently set or available * to request. */ - bzero (&lucd, sizeof(lucd)); - error = copyout(&lucd, args->datap, sizeof(lucd)); + memset(&lucd, 0, u32s * sizeof(lucd[0])); + error = copyout(&lucd, uap->datap, u32s * sizeof(lucd[0])); } return (error); } int -linux_capset(struct thread *td, struct linux_capset_args *args) +linux_capset(struct thread *td, struct linux_capset_args *uap) { struct l_user_cap_header luch; - struct l_user_cap_data lucd; - int error; + struct l_user_cap_data lucd[2]; + int error, i, u32s; - if (args->hdrp == NULL || args->datap == NULL) + if (uap->hdrp == NULL || uap->datap == NULL) return (EFAULT); - error = copyin(args->hdrp, &luch, sizeof(luch)); + error = copyin(uap->hdrp, &luch, sizeof(luch)); if (error != 0) return (error); - if (luch.version != _LINUX_CAPABILITY_VERSION) { + switch (luch.version) { + case _LINUX_CAPABILITY_VERSION_1: + u32s = 1; + break; + case _LINUX_CAPABILITY_VERSION_2: + case _LINUX_CAPABILITY_VERSION_3: + u32s = 2; + break; + default: #ifdef DEBUG if (ldebug(capset)) printf(LMSG("invalid capset capability version 0x%x"), luch.version); #endif - luch.version = _LINUX_CAPABILITY_VERSION; - error = copyout(&luch, args->hdrp, sizeof(luch)); + luch.version = _LINUX_CAPABILITY_VERSION_1; + error = copyout(&luch, uap->hdrp, sizeof(luch)); if (error) return (error); return (EINVAL); @@ -1954,18 +1972,21 @@ linux_capset(struct thread *td, struct linux_capset_ar if (luch.pid) return (EPERM); - error = copyin(args->datap, &lucd, sizeof(lucd)); + error = copyin(uap->datap, &lucd, u32s * sizeof(lucd[0])); if (error != 0) return (error); /* We currently don't support setting any capabilities. */ - if (lucd.effective || lucd.permitted || lucd.inheritable) { - linux_msg(td, - "capset effective=0x%x, permitted=0x%x, " - "inheritable=0x%x is not implemented", - (int)lucd.effective, (int)lucd.permitted, - (int)lucd.inheritable); - return (EPERM); + for (i = 0; i < u32s; i++) { + if (lucd[i].effective || lucd[i].permitted || + lucd[i].inheritable) { + linux_msg(td, + "capset[%d] effective=0x%x, permitted=0x%x, " + "inheritable=0x%x is not implemented", i, + (int)lucd[i].effective, (int)lucd[i].permitted, + (int)lucd[i].inheritable); + return (EPERM); + } } return (0);