mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-06 03:36:04 +00:00
Restore most cases of am_guest_unpriv
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>
This commit is contained in:
parent
477aa378e9
commit
e0010464c7
@ -2678,7 +2678,7 @@ static bool has_snapshots(struct lxc_container *c)
|
|||||||
static bool do_destroy_container(struct lxc_conf *conf) {
|
static bool do_destroy_container(struct lxc_conf *conf) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (am_host_unpriv()) {
|
if (am_guest_unpriv()) {
|
||||||
ret = userns_exec_full(conf, storage_destroy_wrapper, conf,
|
ret = userns_exec_full(conf, storage_destroy_wrapper, conf,
|
||||||
"storage_destroy_wrapper");
|
"storage_destroy_wrapper");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -2800,7 +2800,7 @@ static bool container_destroy(struct lxc_container *c,
|
|||||||
if (ret < 0 || (size_t)ret >= len)
|
if (ret < 0 || (size_t)ret >= len)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (am_host_unpriv())
|
if (am_guest_unpriv())
|
||||||
ret = userns_exec_1(conf, lxc_unlink_exec_wrapper, path,
|
ret = userns_exec_1(conf, lxc_unlink_exec_wrapper, path,
|
||||||
"lxc_unlink_exec_wrapper");
|
"lxc_unlink_exec_wrapper");
|
||||||
else
|
else
|
||||||
@ -2819,7 +2819,7 @@ static bool container_destroy(struct lxc_container *c,
|
|||||||
ret = snprintf(path, len, "%s/%s", p1, c->name);
|
ret = snprintf(path, len, "%s/%s", p1, c->name);
|
||||||
if (ret < 0 || (size_t)ret >= len)
|
if (ret < 0 || (size_t)ret >= len)
|
||||||
goto out;
|
goto out;
|
||||||
if (am_host_unpriv())
|
if (am_guest_unpriv())
|
||||||
ret = userns_exec_full(conf, lxc_rmdir_onedev_wrapper, path,
|
ret = userns_exec_full(conf, lxc_rmdir_onedev_wrapper, path,
|
||||||
"lxc_rmdir_onedev_wrapper");
|
"lxc_rmdir_onedev_wrapper");
|
||||||
else
|
else
|
||||||
@ -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) {
|
if (chown_mapped_root(newpath, c->lxc_conf) < 0) {
|
||||||
ERROR("Error chowning %s to container root", newpath);
|
ERROR("Error chowning %s to container root", newpath);
|
||||||
goto out;
|
goto out;
|
||||||
@ -3680,7 +3680,7 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
|
|||||||
data.c1 = c2;
|
data.c1 = c2;
|
||||||
data.flags = flags;
|
data.flags = flags;
|
||||||
data.hookargs = hookargs;
|
data.hookargs = hookargs;
|
||||||
if (am_host_unpriv())
|
if (am_guest_unpriv())
|
||||||
ret = userns_exec_full(c->lxc_conf, clone_update_rootfs_wrapper,
|
ret = userns_exec_full(c->lxc_conf, clone_update_rootfs_wrapper,
|
||||||
&data, "clone_update_rootfs_wrapper");
|
&data, "clone_update_rootfs_wrapper");
|
||||||
else
|
else
|
||||||
@ -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)
|
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()) {
|
if (am_host_unpriv()) {
|
||||||
ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
|
ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
@ -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)
|
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__);
|
ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -4382,7 +4383,7 @@ static bool do_lxcapi_attach_interface(struct lxc_container *c,
|
|||||||
pid_t init_pid;
|
pid_t init_pid;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (am_host_unpriv()) {
|
if (am_guest_unpriv()) {
|
||||||
ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
|
ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -4421,7 +4422,11 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
|
|||||||
int ret;
|
int ret;
|
||||||
pid_t pid, pid_outside;
|
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__);
|
ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2449,7 +2449,7 @@ int lxc_network_move_created_netdev_priv(const char *lxcpath, const char *lxcnam
|
|||||||
char ifname[IFNAMSIZ];
|
char ifname[IFNAMSIZ];
|
||||||
struct lxc_list *iterator;
|
struct lxc_list *iterator;
|
||||||
|
|
||||||
if (am_host_unpriv())
|
if (am_guest_unpriv())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
lxc_list_for_each(iterator, network) {
|
lxc_list_for_each(iterator, network) {
|
||||||
@ -2487,7 +2487,7 @@ int lxc_create_network_unpriv(const char *lxcpath, const char *lxcname,
|
|||||||
{
|
{
|
||||||
struct lxc_list *iterator;
|
struct lxc_list *iterator;
|
||||||
|
|
||||||
if (!am_host_unpriv())
|
if (!am_guest_unpriv())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
lxc_list_for_each(iterator, network) {
|
lxc_list_for_each(iterator, network) {
|
||||||
|
@ -654,11 +654,11 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
|
|||||||
|
|
||||||
memset(handler, 0, sizeof(*handler));
|
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
|
* care if we are real root only if we are running as root so this
|
||||||
* should be fine.
|
* 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->data_sock[0] = handler->data_sock[1] = -1;
|
||||||
handler->conf = conf;
|
handler->conf = conf;
|
||||||
handler->lxcpath = lxcpath;
|
handler->lxcpath = lxcpath;
|
||||||
|
@ -89,7 +89,7 @@ int aufs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
|
|||||||
if (mkdir_p(new->dest, 0755) < 0)
|
if (mkdir_p(new->dest, 0755) < 0)
|
||||||
return -1;
|
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);
|
WARN("Failed to update ownership of %s", new->dest);
|
||||||
|
|
||||||
if (strcmp(orig->type, "dir") == 0) {
|
if (strcmp(orig->type, "dir") == 0) {
|
||||||
@ -116,7 +116,7 @@ int aufs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
|
|||||||
free(delta);
|
free(delta);
|
||||||
return -1;
|
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);
|
WARN("Failed to update ownership of %s", delta);
|
||||||
|
|
||||||
// the src will be 'aufs:lowerdir:upperdir'
|
// the src will be 'aufs:lowerdir:upperdir'
|
||||||
@ -157,13 +157,13 @@ int aufs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
|
|||||||
free(ndelta);
|
free(ndelta);
|
||||||
return -1;
|
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);
|
WARN("Failed to update ownership of %s", ndelta);
|
||||||
|
|
||||||
struct rsync_data_char rdata;
|
struct rsync_data_char rdata;
|
||||||
rdata.src = odelta;
|
rdata.src = odelta;
|
||||||
rdata.dest = ndelta;
|
rdata.dest = ndelta;
|
||||||
if (am_host_unpriv())
|
if (am_guest_unpriv())
|
||||||
ret = userns_exec_full(conf, lxc_rsync_delta_wrapper,
|
ret = userns_exec_full(conf, lxc_rsync_delta_wrapper,
|
||||||
&rdata, "lxc_rsync_delta_wrapper");
|
&rdata, "lxc_rsync_delta_wrapper");
|
||||||
else
|
else
|
||||||
|
@ -434,7 +434,7 @@ bool btrfs_create_clone(struct lxc_conf *conf, struct lxc_storage *orig,
|
|||||||
/* rsync the contents from source to target */
|
/* rsync the contents from source to target */
|
||||||
data.orig = orig;
|
data.orig = orig;
|
||||||
data.new = new;
|
data.new = new;
|
||||||
if (am_host_unpriv()) {
|
if (am_guest_unpriv()) {
|
||||||
ret = userns_exec_full(conf, lxc_storage_rsync_exec_wrapper,
|
ret = userns_exec_full(conf, lxc_storage_rsync_exec_wrapper,
|
||||||
&data, "lxc_storage_rsync_exec_wrapper");
|
&data, "lxc_storage_rsync_exec_wrapper");
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -466,7 +466,7 @@ bool btrfs_create_snapshot(struct lxc_conf *conf, struct lxc_storage *orig,
|
|||||||
if (ret < 0 && errno != ENOENT)
|
if (ret < 0 && errno != ENOENT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (am_host_unpriv()) {
|
if (am_guest_unpriv()) {
|
||||||
struct rsync_data_char args;
|
struct rsync_data_char args;
|
||||||
|
|
||||||
args.src = orig->src;
|
args.src = orig->src;
|
||||||
|
@ -73,7 +73,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (am_host_unpriv()) {
|
if (am_guest_unpriv()) {
|
||||||
ret = chown_mapped_root(new->dest, conf);
|
ret = chown_mapped_root(new->dest, conf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
WARN("Failed to update ownership of %s", new->dest);
|
WARN("Failed to update ownership of %s", new->dest);
|
||||||
@ -120,7 +120,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (am_host_unpriv()) {
|
if (am_guest_unpriv()) {
|
||||||
ret = chown_mapped_root(delta, conf);
|
ret = chown_mapped_root(delta, conf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
WARN("Failed to update ownership of %s", delta);
|
WARN("Failed to update ownership of %s", delta);
|
||||||
@ -153,7 +153,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (am_host_unpriv()) {
|
if (am_guest_unpriv()) {
|
||||||
ret = chown_mapped_root(work, conf);
|
ret = chown_mapped_root(work, conf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
WARN("Failed to update ownership of %s", work);
|
WARN("Failed to update ownership of %s", work);
|
||||||
@ -224,7 +224,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (am_host_unpriv()) {
|
if (am_guest_unpriv()) {
|
||||||
ret = chown_mapped_root(ndelta, conf);
|
ret = chown_mapped_root(ndelta, conf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
WARN("Failed to update ownership of %s",
|
WARN("Failed to update ownership of %s",
|
||||||
@ -265,7 +265,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (am_host_unpriv()) {
|
if (am_guest_unpriv()) {
|
||||||
ret = chown_mapped_root(work, conf);
|
ret = chown_mapped_root(work, conf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
WARN("Failed to update ownership of %s", work);
|
WARN("Failed to update ownership of %s", work);
|
||||||
@ -960,7 +960,7 @@ static int ovl_do_rsync(const char *src, const char *dest,
|
|||||||
|
|
||||||
rdata.src = (char *)src;
|
rdata.src = (char *)src;
|
||||||
rdata.dest = (char *)dest;
|
rdata.dest = (char *)dest;
|
||||||
if (am_host_unpriv())
|
if (am_guest_unpriv())
|
||||||
ret = userns_exec_full(conf, lxc_rsync_exec_wrapper, &rdata,
|
ret = userns_exec_full(conf, lxc_rsync_exec_wrapper, &rdata,
|
||||||
"lxc_rsync_exec_wrapper");
|
"lxc_rsync_exec_wrapper");
|
||||||
else
|
else
|
||||||
|
@ -406,7 +406,7 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
|
|||||||
if (!bdevtype && !keepbdevtype && snap && !strcmp(orig->type, "dir"))
|
if (!bdevtype && !keepbdevtype && snap && !strcmp(orig->type, "dir"))
|
||||||
bdevtype = "overlay";
|
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",
|
ERROR("Unsupported snapshot type \"%s\" for unprivileged users",
|
||||||
bdevtype ? bdevtype : "(null)");
|
bdevtype ? bdevtype : "(null)");
|
||||||
goto on_error_put_orig;
|
goto on_error_put_orig;
|
||||||
@ -505,7 +505,7 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
|
|||||||
else
|
else
|
||||||
src_no_prefix = lxc_storage_get_path(new->src, new->type);
|
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);
|
ret = chown_mapped_root(src_no_prefix, c->lxc_conf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
WARN("Failed to chown \"%s\"", new->src);
|
WARN("Failed to chown \"%s\"", new->src);
|
||||||
@ -518,7 +518,7 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
|
|||||||
/* rsync the contents from source to target */
|
/* rsync the contents from source to target */
|
||||||
data.orig = orig;
|
data.orig = orig;
|
||||||
data.new = new;
|
data.new = new;
|
||||||
if (am_host_unpriv())
|
if (am_guest_unpriv())
|
||||||
ret = userns_exec_full(c->lxc_conf,
|
ret = userns_exec_full(c->lxc_conf,
|
||||||
lxc_storage_rsync_exec_wrapper, &data,
|
lxc_storage_rsync_exec_wrapper, &data,
|
||||||
"lxc_storage_rsync_exec_wrapper");
|
"lxc_storage_rsync_exec_wrapper");
|
||||||
|
Loading…
Reference in New Issue
Block a user