[lxc-devel] [PATCH] handle unprivileged user calls more gracefully

S.Çağlar Onur caglar at 10ur.org
Fri Jan 17 20:01:46 UTC 2014


Return an error if the function is not supposed to be called by an unprivileged user.
Otherwise those calls fail in the middle of their execution with different reasons.

Signed-off-by: S.Çağlar Onur <caglar at 10ur.org>
---
 src/lxc/lxccontainer.c | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 0bebdff..8d49e94 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -64,6 +64,10 @@
 
 lxc_log_define(lxc_container, lxc);
 
+static bool am_unpriv(struct lxc_container *c) {
+	return c->lxc_conf && geteuid() != 0 && !lxc_list_empty(&c->lxc_conf->id_map);
+}
+
 static bool file_exists(const char *f)
 {
 	struct stat statbuf;
@@ -1489,6 +1493,9 @@ static char** lxcapi_get_interfaces(struct lxc_container *c)
 	char **interfaces = NULL;
 	int old_netns = -1, new_netns = -1;
 
+	if (am_unpriv(c))
+		goto out;
+
 	if (!enter_to_ns(c, &old_netns, &new_netns))
 		goto out;
 
@@ -1538,6 +1545,9 @@ static char** lxcapi_get_ips(struct lxc_container *c, const char* interface, con
 	char *address = NULL;
 	int old_netns = -1, new_netns = -1;
 
+	if (am_unpriv(c))
+		goto out;
+
 	if (!enter_to_ns(c, &old_netns, &new_netns))
 		goto out;
 
@@ -1818,7 +1828,7 @@ static int lxc_rmdir_onedev_wrapper(void *data)
 static bool lxcapi_destroy(struct lxc_container *c)
 {
 	struct bdev *r = NULL;
-	bool bret = false, am_unpriv;
+	bool bret = false;
 	int ret;
 
 	if (!c || !lxcapi_is_defined(c))
@@ -1833,14 +1843,12 @@ static bool lxcapi_destroy(struct lxc_container *c)
 		goto out;
 	}
 
-	am_unpriv = c->lxc_conf && geteuid() != 0 && !lxc_list_empty(&c->lxc_conf->id_map);
-
 	if (c->lxc_conf && has_snapshots(c)) {
 		ERROR("container %s has dependent snapshots", c->name);
 		goto out;
 	}
 
-	if (!am_unpriv && c->lxc_conf->rootfs.path && c->lxc_conf->rootfs.mount) {
+	if (!am_unpriv(c) && c->lxc_conf->rootfs.path && c->lxc_conf->rootfs.mount) {
 		r = bdev_init(c->lxc_conf->rootfs.path, c->lxc_conf->rootfs.mount, NULL);
 		if (r) {
 			if (r->ops->destroy(r) < 0) {
@@ -1857,7 +1865,7 @@ static bool lxcapi_destroy(struct lxc_container *c)
 	const char *p1 = lxcapi_get_config_path(c);
 	char *path = alloca(strlen(p1) + strlen(c->name) + 2);
 	sprintf(path, "%s/%s", p1, c->name);
-	if (am_unpriv)
+	if (am_unpriv(c))
 		ret = userns_exec_1(c->lxc_conf, lxc_rmdir_onedev_wrapper, path);
 	else
 		ret = lxc_rmdir_onedev(path);
@@ -2406,6 +2414,9 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n
 	if (!c || !c->is_defined(c))
 		return NULL;
 
+	if (am_unpriv(c))
+		return NULL;
+
 	if (container_mem_lock(c))
 		return NULL;
 
@@ -2587,6 +2598,9 @@ static int lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
 	struct lxc_container *c2;
 	char snappath[MAXPATHLEN], newname[20];
 
+	if (am_unpriv(c))
+		return -1;
+
 	// /var/lib/lxc -> /var/lib/lxcsnaps \0
 	ret = snprintf(snappath, MAXPATHLEN, "%ssnaps/%s", c->config_path, c->name);
 	if (ret < 0 || ret >= MAXPATHLEN)
@@ -2802,6 +2816,9 @@ static bool lxcapi_snapshot_restore(struct lxc_container *c, const char *snapnam
 	if (!c || !c->name || !c->config_path)
 		return false;
 
+	if (am_unpriv(c))
+		return false;
+
 	bdev = bdev_init(c->lxc_conf->rootfs.path, c->lxc_conf->rootfs.mount, NULL);
 	if (!bdev) {
 		ERROR("Failed to find original backing store type");
@@ -2851,6 +2868,9 @@ static bool lxcapi_snapshot_destroy(struct lxc_container *c, const char *snapnam
 	if (!c || !c->name || !c->config_path)
 		return false;
 
+	if (am_unpriv(c))
+		return false;
+
 	ret = snprintf(clonelxcpath, MAXPATHLEN, "%ssnaps/%s", c->config_path, c->name);
 	if (ret < 0 || ret >= MAXPATHLEN)
 		goto err;
@@ -2888,6 +2908,9 @@ static bool add_remove_device_node(struct lxc_container *c, const char *src_path
 	char *directory_path = NULL;
 	const char *p;
 
+	if (am_unpriv(c))
+		goto out;
+
 	/* make sure container is running */
 	if (!c->is_running(c)) {
 		ERROR("container is not running");
-- 
1.8.3.2



More information about the lxc-devel mailing list