svn commit: r346834 - stable/11/sys/compat/linux
Dmitry Chagin
dchagin at FreeBSD.org
Sun Apr 28 14:06:23 UTC 2019
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);
More information about the svn-src-stable
mailing list