Author: dchagin Date: Sun Apr 28 14:06:22 2019 New Revision: 346834 URL: https://svnweb.freebsd.org/changeset/base/346834
Log: MFC r335387 (by emaste@): 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.) Modified: stable/11/sys/compat/linux/linux_misc.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/compat/linux/linux_misc.c ============================================================================== --- stable/11/sys/compat/linux/linux_misc.c Sun Apr 28 14:05:05 2019 (r346833) +++ stable/11/sys/compat/linux/linux_misc.c Sun Apr 28 14:06:22 2019 (r346834) @@ -1864,7 +1864,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; @@ -1878,27 +1880,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); @@ -1907,42 +1917,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); @@ -1951,18 +1969,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); _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"