diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2014-07-09 20:14:17 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2014-07-09 20:14:17 +0000 |
commit | 40fa04c2ff6f1c2824bd838efaad336d9336135e (patch) | |
tree | a64685cef5bae7fc40d9cbc2b9934eef5113c064 /usr/src | |
parent | 63db251a11ab768d92fd5bb20e818fc268222854 (diff) | |
download | illumos-joyent-40fa04c2ff6f1c2824bd838efaad336d9336135e.tar.gz |
OS-3192 lxbrand ubuntu 14 ping error: cap_get_proc: Function not implemented
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/id.c | 85 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/lx_brand.c | 4 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h | 2 |
3 files changed, 87 insertions, 4 deletions
diff --git a/usr/src/lib/brand/lx/lx_brand/common/id.c b/usr/src/lib/brand/lx/lx_brand/common/id.c index a9987cea52..eec5725dfc 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/id.c +++ b/usr/src/lib/brand/lx/lx_brand/common/id.c @@ -22,10 +22,9 @@ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2014 Joyent, Inc. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/systm.h> #include <sys/errno.h> @@ -44,6 +43,29 @@ #include <string.h> #include <sys/lx_misc.h> +typedef struct { + uint32_t version; + int pid; +} lx_cap_user_header_t; + +typedef struct { + uint32_t effective; + uint32_t permitted; + uint32_t inheritable; +} lx_cap_user_data_t; + +#define LX_CAPABILITY_VERSION_1 0x19980330 +#define LX_CAPABILITY_VERSION_2 0x20071026 /* deprecated by Linux */ +#define LX_CAPABILITY_VERSION_3 0x20080522 + +/* + * All capabailities for super-user and basic capabilities for regular user. + * Linux current defines 38 capabilities, the last being CAP_AUDIT_READ. + * However, for a 32-bit kernel it looks like we only pass back up to + * CAP_SETFCAP. + */ +#define LX_ALL_CAPABILITIES 0xFFFFFFFFU + int lx_setuid16(uintptr_t uid) { @@ -267,3 +289,62 @@ lx_setfsgid(uintptr_t fsgid) { return (getegid()); } + +/* + * As a future enhancement we could investigate mapping Linux capabilities + * into Illumos privileges, but for now we simply pretend we have capabilities + * and give all of them back if the euid is 0. Likewise, we do nothing when + * setting capabilities. We could also keep track of which capabilities have + * been set so we could hand back that subset, instead of always saying we + * have all of them enabled. + */ +int +lx_capget(uintptr_t p1, uintptr_t p2) +{ + lx_cap_user_header_t *chp = (lx_cap_user_header_t *)p1; + lx_cap_user_data_t *cdp = (lx_cap_user_data_t *)p2; + lx_cap_user_header_t ch; + lx_cap_user_data_t cd; + + if (uucopy(chp, &ch, sizeof (ch)) != 0) + return (-errno); + + if (ch.version != LX_CAPABILITY_VERSION_1 && + ch.version != LX_CAPABILITY_VERSION_2 && + ch.version != LX_CAPABILITY_VERSION_3) + return (-EINVAL); + + /* A null data pointer is used when querying supported version */ + if (cdp == 0) + return (0); + + if (geteuid() == 0) { + /* root, you have all capabilities */ + cd.effective = LX_ALL_CAPABILITIES; + cd.permitted = LX_ALL_CAPABILITIES; + cd.inheritable = 0; + } else { + /* not root and trying to set another process's capabilities */ + if (ch.pid != 0) + return (-EPERM); + + /* not root, you have no capabilities */ + cd.effective = 0; + cd.permitted = 0; + cd.inheritable = 0; + } + + if (uucopy(&cd, cdp, sizeof (cd)) != 0) + return (-errno); + + return (0); +} + +/*ARGSUSED*/ +int +lx_capset(uintptr_t p1, uintptr_t p2) +{ + if (geteuid() == 0) + return (0); + return (-EPERM); +} diff --git a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c index ae04c178a4..f90cba9fb9 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c +++ b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c @@ -1119,8 +1119,8 @@ static struct lx_sysent sysents[] = { {"pwrite64", lx_pwrite64, 0, 5}, /* 181 */ {"chown16", lx_chown16, 0, 3}, /* 182 */ {"getcwd", lx_getcwd, 0, 2}, /* 183 */ - {"capget", NULL, NOSYS_NO_EQUIV, 0}, /* 184 */ - {"capset", NULL, NOSYS_NO_EQUIV, 0}, /* 185 */ + {"capget", lx_capget, 0, 2}, /* 184 */ + {"capset", lx_capset, 0, 2}, /* 185 */ {"sigaltstack", lx_sigaltstack, 0, 2}, /* 186 */ {"sendfile", lx_sendfile, 0, 4}, /* 187 */ {"getpmsg", NULL, NOSYS_OBSOLETE, 0}, /* 188 */ diff --git a/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h b/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h index d299c93015..ba6a51d124 100644 --- a/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h +++ b/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h @@ -122,6 +122,8 @@ extern int lx_getresuid16(uintptr_t, uintptr_t, uintptr_t); extern int lx_getresgid16(uintptr_t, uintptr_t, uintptr_t); extern int lx_getresuid(uintptr_t, uintptr_t, uintptr_t); extern int lx_getresgid(uintptr_t, uintptr_t, uintptr_t); +extern int lx_capget(uintptr_t, uintptr_t); +extern int lx_capset(uintptr_t, uintptr_t); extern int lx_setuid16(uintptr_t); extern int lx_setreuid16(uintptr_t, uintptr_t); |