Skip to content

Commit

Permalink
Restore most cases of am_guest_unpriv
Browse files Browse the repository at this point in the history
The only cases where we really need to be privileged with respect
to the host is when we are trying to mknod, and in some cases
to do with a physical network device.  This patch leaves the
detection of the network device cases as a TODO.

This should fix the currently broken case of starting a privileged
container with at least one veth nic, nested inside an unprivileged
container.

Cc: Tycho Andersen <tycho@tycho.ws>
Signed-off-by: Serge Hallyn <shallyn@cisco.com>
  • Loading branch information
hallyn committed Feb 8, 2018
1 parent 477aa37 commit e001046
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 27 deletions.
21 changes: 13 additions & 8 deletions src/lxc/lxccontainer.c
Expand Up @@ -2678,7 +2678,7 @@ static bool has_snapshots(struct lxc_container *c)
static bool do_destroy_container(struct lxc_conf *conf) {
int ret;

if (am_host_unpriv()) {
if (am_guest_unpriv()) {
ret = userns_exec_full(conf, storage_destroy_wrapper, conf,
"storage_destroy_wrapper");
if (ret < 0)
Expand Down Expand Up @@ -2800,7 +2800,7 @@ static bool container_destroy(struct lxc_container *c,
if (ret < 0 || (size_t)ret >= len)
goto out;

if (am_host_unpriv())
if (am_guest_unpriv())
ret = userns_exec_1(conf, lxc_unlink_exec_wrapper, path,
"lxc_unlink_exec_wrapper");
else
Expand All @@ -2819,7 +2819,7 @@ static bool container_destroy(struct lxc_container *c,
ret = snprintf(path, len, "%s/%s", p1, c->name);
if (ret < 0 || (size_t)ret >= len)
goto out;
if (am_host_unpriv())
if (am_guest_unpriv())
ret = userns_exec_full(conf, lxc_rmdir_onedev_wrapper, path,
"lxc_rmdir_onedev_wrapper");
else
Expand Down Expand Up @@ -3602,7 +3602,7 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
}
}

if (am_host_unpriv()) {
if (am_guest_unpriv()) {
if (chown_mapped_root(newpath, c->lxc_conf) < 0) {
ERROR("Error chowning %s to container root", newpath);
goto out;
Expand Down Expand Up @@ -3680,7 +3680,7 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
data.c1 = c2;
data.flags = flags;
data.hookargs = hookargs;
if (am_host_unpriv())
if (am_guest_unpriv())
ret = userns_exec_full(c->lxc_conf, clone_update_rootfs_wrapper,
&data, "clone_update_rootfs_wrapper");
else
Expand Down Expand Up @@ -4355,6 +4355,7 @@ static bool add_remove_device_node(struct lxc_container *c, const char *src_path

static bool do_lxcapi_add_device_node(struct lxc_container *c, const char *src_path, const char *dest_path)
{
// cannot mknod if we're not privileged wrt init_user_ns
if (am_host_unpriv()) {
ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
return false;
Expand All @@ -4366,7 +4367,7 @@ WRAP_API_2(bool, lxcapi_add_device_node, const char *, const char *)

static bool do_lxcapi_remove_device_node(struct lxc_container *c, const char *src_path, const char *dest_path)
{
if (am_host_unpriv()) {
if (am_guest_unpriv()) {
ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
return false;
}
Expand All @@ -4382,7 +4383,7 @@ static bool do_lxcapi_attach_interface(struct lxc_container *c,
pid_t init_pid;
int ret = 0;

if (am_host_unpriv()) {
if (am_guest_unpriv()) {
ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
return false;
}
Expand Down Expand Up @@ -4421,7 +4422,11 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
int ret;
pid_t pid, pid_outside;

if (am_host_unpriv()) {
/*
* TODO - if this is a physical device, then we need am_host_unpriv.
* But for other types guest privilege suffices.
*/
if (am_guest_unpriv()) {
ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions src/lxc/network.c
Expand Up @@ -2449,7 +2449,7 @@ int lxc_network_move_created_netdev_priv(const char *lxcpath, const char *lxcnam
char ifname[IFNAMSIZ];
struct lxc_list *iterator;

if (am_host_unpriv())
if (am_guest_unpriv())
return 0;

lxc_list_for_each(iterator, network) {
Expand Down Expand Up @@ -2487,7 +2487,7 @@ int lxc_create_network_unpriv(const char *lxcpath, const char *lxcname,
{
struct lxc_list *iterator;

if (!am_host_unpriv())
if (!am_guest_unpriv())
return 0;

lxc_list_for_each(iterator, network) {
Expand Down
4 changes: 2 additions & 2 deletions src/lxc/start.c
Expand Up @@ -654,11 +654,11 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,

memset(handler, 0, sizeof(*handler));

/* Note that am_host_unpriv() checks the effective uid. We probably don't
/* Note that am_guest_unpriv() checks the effective uid. We probably don't
* care if we are real root only if we are running as root so this
* should be fine.
*/
handler->am_root = !am_host_unpriv();
handler->am_root = !am_guest_unpriv();
handler->data_sock[0] = handler->data_sock[1] = -1;
handler->conf = conf;
handler->lxcpath = lxcpath;
Expand Down
8 changes: 4 additions & 4 deletions src/lxc/storage/aufs.c
Expand Up @@ -89,7 +89,7 @@ int aufs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
if (mkdir_p(new->dest, 0755) < 0)
return -1;

if (am_host_unpriv() && chown_mapped_root(new->dest, conf) < 0)
if (am_guest_unpriv() && chown_mapped_root(new->dest, conf) < 0)
WARN("Failed to update ownership of %s", new->dest);

if (strcmp(orig->type, "dir") == 0) {
Expand All @@ -116,7 +116,7 @@ int aufs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
free(delta);
return -1;
}
if (am_host_unpriv() && chown_mapped_root(delta, conf) < 0)
if (am_guest_unpriv() && chown_mapped_root(delta, conf) < 0)
WARN("Failed to update ownership of %s", delta);

// the src will be 'aufs:lowerdir:upperdir'
Expand Down Expand Up @@ -157,13 +157,13 @@ int aufs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
free(ndelta);
return -1;
}
if (am_host_unpriv() && chown_mapped_root(ndelta, conf) < 0)
if (am_guest_unpriv() && chown_mapped_root(ndelta, conf) < 0)
WARN("Failed to update ownership of %s", ndelta);

struct rsync_data_char rdata;
rdata.src = odelta;
rdata.dest = ndelta;
if (am_host_unpriv())
if (am_guest_unpriv())
ret = userns_exec_full(conf, lxc_rsync_delta_wrapper,
&rdata, "lxc_rsync_delta_wrapper");
else
Expand Down
4 changes: 2 additions & 2 deletions src/lxc/storage/btrfs.c
Expand Up @@ -434,7 +434,7 @@ bool btrfs_create_clone(struct lxc_conf *conf, struct lxc_storage *orig,
/* rsync the contents from source to target */
data.orig = orig;
data.new = new;
if (am_host_unpriv()) {
if (am_guest_unpriv()) {
ret = userns_exec_full(conf, lxc_storage_rsync_exec_wrapper,
&data, "lxc_storage_rsync_exec_wrapper");
if (ret < 0) {
Expand Down Expand Up @@ -466,7 +466,7 @@ bool btrfs_create_snapshot(struct lxc_conf *conf, struct lxc_storage *orig,
if (ret < 0 && errno != ENOENT)
return false;

if (am_host_unpriv()) {
if (am_guest_unpriv()) {
struct rsync_data_char args;

args.src = orig->src;
Expand Down
12 changes: 6 additions & 6 deletions src/lxc/storage/overlay.c
Expand Up @@ -73,7 +73,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
return -1;
}

if (am_host_unpriv()) {
if (am_guest_unpriv()) {
ret = chown_mapped_root(new->dest, conf);
if (ret < 0)
WARN("Failed to update ownership of %s", new->dest);
Expand Down Expand Up @@ -120,7 +120,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
return -1;
}

if (am_host_unpriv()) {
if (am_guest_unpriv()) {
ret = chown_mapped_root(delta, conf);
if (ret < 0)
WARN("Failed to update ownership of %s", delta);
Expand Down Expand Up @@ -153,7 +153,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
return -1;
}

if (am_host_unpriv()) {
if (am_guest_unpriv()) {
ret = chown_mapped_root(work, conf);
if (ret < 0)
WARN("Failed to update ownership of %s", work);
Expand Down Expand Up @@ -224,7 +224,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
return -1;
}

if (am_host_unpriv()) {
if (am_guest_unpriv()) {
ret = chown_mapped_root(ndelta, conf);
if (ret < 0)
WARN("Failed to update ownership of %s",
Expand Down Expand Up @@ -265,7 +265,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
return -1;
}

if (am_host_unpriv()) {
if (am_guest_unpriv()) {
ret = chown_mapped_root(work, conf);
if (ret < 0)
WARN("Failed to update ownership of %s", work);
Expand Down Expand Up @@ -960,7 +960,7 @@ static int ovl_do_rsync(const char *src, const char *dest,

rdata.src = (char *)src;
rdata.dest = (char *)dest;
if (am_host_unpriv())
if (am_guest_unpriv())
ret = userns_exec_full(conf, lxc_rsync_exec_wrapper, &rdata,
"lxc_rsync_exec_wrapper");
else
Expand Down
6 changes: 3 additions & 3 deletions src/lxc/storage/storage.c
Expand Up @@ -406,7 +406,7 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
if (!bdevtype && !keepbdevtype && snap && !strcmp(orig->type, "dir"))
bdevtype = "overlay";

if (am_host_unpriv() && !unpriv_snap_allowed(orig, bdevtype, snap, maybe_snap)) {
if (am_guest_unpriv() && !unpriv_snap_allowed(orig, bdevtype, snap, maybe_snap)) {
ERROR("Unsupported snapshot type \"%s\" for unprivileged users",
bdevtype ? bdevtype : "(null)");
goto on_error_put_orig;
Expand Down Expand Up @@ -505,7 +505,7 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
else
src_no_prefix = lxc_storage_get_path(new->src, new->type);

if (am_host_unpriv()) {
if (am_guest_unpriv()) {
ret = chown_mapped_root(src_no_prefix, c->lxc_conf);
if (ret < 0)
WARN("Failed to chown \"%s\"", new->src);
Expand All @@ -518,7 +518,7 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
/* rsync the contents from source to target */
data.orig = orig;
data.new = new;
if (am_host_unpriv())
if (am_guest_unpriv())
ret = userns_exec_full(c->lxc_conf,
lxc_storage_rsync_exec_wrapper, &data,
"lxc_storage_rsync_exec_wrapper");
Expand Down

0 comments on commit e001046

Please sign in to comment.