summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2014-07-09 20:14:17 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2014-07-09 20:14:17 +0000
commit40fa04c2ff6f1c2824bd838efaad336d9336135e (patch)
treea64685cef5bae7fc40d9cbc2b9934eef5113c064 /usr/src
parent63db251a11ab768d92fd5bb20e818fc268222854 (diff)
downloadillumos-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.c85
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/lx_brand.c4
-rw-r--r--usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h2
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);