[lxc-devel] [patch -lxc 1/6] remove/restore effective capabilities

Daniel Lezcano dlezcano at fr.ibm.com
Mon Jul 12 12:56:43 UTC 2010


This patch adds the functions to drop the 'effective' capabilities and
restore them from the 'permitted' capabilities.

When the command is run as 'root' we do nothing.
When the command is run as 'lambda' user, we drop the effective capabilities
When the command is run as 'root' but real uid is not root, we keep the capabilies,
switch to real uid, and drop the effective capabilities.

This approach is compatible for root user, lambda + file capabilities
and lambda + setuid.

Signed-off-by: Daniel Lezcano <dlezcano at fr.ibm.com>
---
 src/lxc/Makefile.am |    5 +-
 src/lxc/caps.c      |  135 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/caps.h      |   28 +++++++++++
 3 files changed, 166 insertions(+), 2 deletions(-)
 create mode 100644 src/lxc/caps.c
 create mode 100644 src/lxc/caps.h

diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am
index 3cbd6c0..133f102 100644
--- a/src/lxc/Makefile.am
+++ b/src/lxc/Makefile.am
@@ -5,6 +5,7 @@ pkginclude_HEADERS = \
 		monitor.h \
 		utils.h \
 		namespace.h \
+		caps.h \
 		lxc.h \
 		cgroup.h \
 		conf.h \
@@ -44,6 +45,7 @@ liblxc_so_SOURCES = \
         rtnl.c rtnl.h \
         genl.c genl.h \
 	\
+	caps.c caps.h \
 	mainloop.c mainloop.h \
 	af_unix.c af_unix.h \
 	\
@@ -90,7 +92,7 @@ pkglib_PROGRAMS = \
 	lxc-init
 
 AM_LDFLAGS=-Wl,-E -Wl,-rpath -Wl,$(libdir)
-LDADD=liblxc.so
+LDADD=liblxc.so @CAP_LIBS@
 
 lxc_attach_SOURCES = lxc_attach.c
 lxc_cgroup_SOURCES = lxc_cgroup.c
@@ -100,7 +102,6 @@ lxc_execute_SOURCES = lxc_execute.c
 lxc_freeze_SOURCES = lxc_freeze.c
 lxc_info_SOURCES = lxc_info.c
 lxc_init_SOURCES = lxc_init.c
-lxc_init_LDADD = $(LDADD) @CAP_LIBS@
 lxc_monitor_SOURCES = lxc_monitor.c
 lxc_restart_SOURCES = lxc_restart.c
 lxc_start_SOURCES = lxc_start.c
diff --git a/src/lxc/caps.c b/src/lxc/caps.c
new file mode 100644
index 0000000..2cd79cd
--- /dev/null
+++ b/src/lxc/caps.c
@@ -0,0 +1,135 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <dlezcano at fr.ibm.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/prctl.h>
+#include <sys/capability.h>
+
+#include "log.h"
+
+lxc_log_define(lxc_caps, lxc);
+
+int lxc_caps_down(void)
+{
+	cap_t caps;
+	int ret;
+
+	caps = cap_get_proc();
+	if (!caps) {
+		ERROR("failed to cap_get_proc: %m");
+		return -1;
+	}
+
+	ret = cap_clear_flag(caps, CAP_EFFECTIVE);
+	if (ret) {
+		ERROR("failed to cap_clear_flag: %m");
+		goto out;
+	}
+
+	ret = cap_set_proc(caps);
+	if (ret) {
+		ERROR("failed to cap_set_proc: %m");
+		goto out;
+	}
+
+out:
+	cap_free(caps);
+        return 0;
+}
+
+int lxc_caps_up(void)
+{
+	cap_t caps;
+	cap_value_t cap;
+	int ret;
+
+	caps = cap_get_proc();
+	if (!caps) {
+		ERROR("failed to cap_get_proc: %m");
+		return -1;
+	}
+
+	for (cap = 0; cap <= CAP_LAST_CAP; cap++) {
+
+		cap_flag_value_t flag;
+
+		ret = cap_get_flag(caps, cap, CAP_PERMITTED, &flag);
+		if (ret) {
+			ERROR("failed to cap_get_flag: %m");
+			goto out;
+		}
+
+		ret = cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap, flag);
+		if (ret) {
+			ERROR("failed to cap_set_flag: %m");
+			goto out;
+		}
+	}
+
+	ret = cap_set_proc(caps);
+	if (ret) {
+		ERROR("failed to cap_set_proc: %m");
+		goto out;
+	}
+
+out:
+	cap_free(caps);
+        return 0;
+}
+
+int lxc_caps_init(void)
+{
+	uid_t uid = getuid();
+	gid_t gid = getgid();
+	uid_t euid = geteuid();
+
+	if (!uid) {
+		INFO("command is run as 'root'");
+		return 0;
+	}
+
+	if (uid && !euid) {
+		INFO("command is run as setuid root (uid : %d)", uid);
+
+		if (prctl(PR_SET_KEEPCAPS, 1)) {
+			ERROR("failed to 'PR_SET_KEEPCAPS': %m");
+			return -1;
+		}
+
+		if (setresgid(gid, gid, gid)) {
+			ERROR("failed to change gid to '%d': %m", gid);
+			return -1;
+		}
+
+		if (setresuid(uid, uid, uid)) {
+			ERROR("failed to change uid to '%d': %m", uid);
+			return -1;
+		}
+	}
+
+	if (uid == euid)
+		INFO("command is run as user '%d'", uid);
+
+	return 0;
+}
diff --git a/src/lxc/caps.h b/src/lxc/caps.h
new file mode 100644
index 0000000..bdc248b
--- /dev/null
+++ b/src/lxc/caps.h
@@ -0,0 +1,28 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <dlezcano at fr.ibm.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _caps_h
+#define _caps_h
+int lxc_caps_down(void);
+int lxc_caps_up(void);
+int lxc_caps_init(void);
+#endif
-- 
1.7.0.4





More information about the lxc-devel mailing list