From: Christian Brauner Date: Wed, 25 Aug 2021 20:38:18 +0000 (+0200) Subject: conf: port id_map to new list type X-Git-Tag: lxc-5.0.0~102^2~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0589d744f699a4efb98079f33ddeece6f5d7c8b9;p=thirdparty%2Flxc.git conf: port id_map to new list type Signed-off-by: Christian Brauner --- diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index 23aef495c..e4d8243a1 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -575,7 +575,7 @@ __cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops, if (ret < 0) WARN("Failed to detach bpf program from cgroup"); - if (!lxc_list_empty(&handler->conf->id_map)) { + if (!list_empty(&handler->conf->id_map)) { struct generic_userns_exec_data wrap = { .conf = handler->conf, .path_prune = ops->container_limit_cgroup, @@ -1363,7 +1363,7 @@ __cgfsng_ops static bool cgfsng_chown(struct cgroup_ops *ops, if (!conf) return ret_set_errno(false, EINVAL); - if (lxc_list_empty(&conf->id_map)) + if (list_empty(&conf->id_map)) return true; wrap.origuid = geteuid(); @@ -2289,7 +2289,7 @@ static int __cg_unified_attach(const struct hierarchy *h, if (unified_fd < 0) return ret_errno(EBADF); - if (!lxc_list_empty(&conf->id_map)) { + if (!list_empty(&conf->id_map)) { struct userns_exec_unified_attach_data args = { .conf = conf, .unified_fd = unified_fd, @@ -3344,7 +3344,7 @@ static int initialize_cgroups(struct cgroup_ops *ops, struct lxc_conf *conf) */ ops->dfd_mnt = dfd; - ret = __initialize_cgroups(ops, conf->cgroup_meta.relative, !lxc_list_empty(&conf->id_map)); + ret = __initialize_cgroups(ops, conf->cgroup_meta.relative, !list_empty(&conf->id_map)); if (ret < 0) return syserror_ret(ret, "Failed to initialize cgroups"); @@ -3421,7 +3421,7 @@ static int __unified_attach_fd(const struct lxc_conf *conf, int fd_unified, pid_ { int ret; - if (!lxc_list_empty(&conf->id_map)) { + if (!list_empty(&conf->id_map)) { struct userns_exec_unified_attach_data args = { .conf = conf, .unified_fd = fd_unified, diff --git a/src/lxc/cmd/lxc_usernsexec.c b/src/lxc/cmd/lxc_usernsexec.c index 26022c806..fb560bf71 100644 --- a/src/lxc/cmd/lxc_usernsexec.c +++ b/src/lxc/cmd/lxc_usernsexec.c @@ -114,11 +114,10 @@ static int do_child(void *vargv) return -1; } -static struct lxc_list active_map; +static LIST_HEAD(active_map); static int add_map_entry(long host_id, long ns_id, long range, int which) { - struct lxc_list *tmp = NULL; struct id_map *newmap; newmap = malloc(sizeof(*newmap)); @@ -129,14 +128,8 @@ static int add_map_entry(long host_id, long ns_id, long range, int which) newmap->nsid = ns_id; newmap->range = range; newmap->idtype = which; - tmp = malloc(sizeof(*tmp)); - if (!tmp) { - free(newmap); - return -1; - } - tmp->elem = newmap; - lxc_list_add_tail(&active_map, tmp); + list_add_tail(&newmap->head, &active_map); return 0; } @@ -280,11 +273,9 @@ static bool do_map_self(void) { struct id_map *map; long nsuid = 0, nsgid = 0; - struct lxc_list *tmp = NULL; int ret; - lxc_list_for_each(tmp, &active_map) { - map = tmp->elem; + list_for_each_entry(map, &active_map, head) { if (map->idtype == ID_TYPE_UID) { if (is_in_ns_range(nsuid, map)) nsuid += map->range; @@ -336,8 +327,6 @@ int main(int argc, char *argv[]) } } - lxc_list_init(&active_map); - while ((c = getopt(argc, argv, "m:hs")) != EOF) { switch (c) { case 'm': @@ -359,7 +348,7 @@ int main(int argc, char *argv[]) } }; - if (lxc_list_empty(&active_map)) { + if (list_empty(&active_map)) { ret = find_default_map(); if (ret < 0) { fprintf(stderr, "Failed to find subuid or subgid allocation\n"); diff --git a/src/lxc/conf.c b/src/lxc/conf.c index f0c6c74be..11f42714b 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -619,7 +619,7 @@ int lxc_rootfs_prepare_parent(struct lxc_handler *handler) int ret; const char *path_source; - if (lxc_list_empty(&handler->conf->id_map)) + if (list_empty(&handler->conf->id_map)) return 0; if (is_empty_string(rootfs->mnt_opts.userns_path)) @@ -1616,7 +1616,6 @@ static const struct id_map *find_mapped_nsid_entry(const struct lxc_conf *conf, unsigned id, enum idtype idtype) { - struct lxc_list *it; struct id_map *map; struct id_map *retmap = NULL; @@ -1629,8 +1628,7 @@ static const struct id_map *find_mapped_nsid_entry(const struct lxc_conf *conf, return conf->root_nsgid_map; } - lxc_list_for_each(it, &conf->id_map) { - map = it->elem; + list_for_each_entry(map, &conf->id_map, head) { if (map->idtype != idtype) continue; @@ -3387,7 +3385,7 @@ struct lxc_conf *lxc_conf_init(void) lxc_list_init(&new->mount_list); lxc_list_init(&new->caps); lxc_list_init(&new->keepcaps); - lxc_list_init(&new->id_map); + INIT_LIST_HEAD(&new->id_map); new->root_nsuid_map = NULL; new->root_nsgid_map = NULL; lxc_list_init(&new->includes); @@ -3528,24 +3526,22 @@ static int lxc_map_ids_exec_wrapper(void *args) return -1; } -static struct id_map *find_mapped_hostid_entry(const struct lxc_list *idmap, +static struct id_map *find_mapped_hostid_entry(const struct list_head *idmap, unsigned id, enum idtype idtype); -int lxc_map_ids(struct lxc_list *idmap, pid_t pid) +int lxc_map_ids(struct list_head *idmap, pid_t pid) { - int fill, left; + int hostuid, hostgid, fill, left; char u_or_g; char *pos; char cmd_output[PATH_MAX]; struct id_map *map; - struct lxc_list *iterator; enum idtype type; int ret = 0, gidmap = 0, uidmap = 0; char mapbuf[STRLITERALLEN("new@idmap") + STRLITERALLEN(" ") + INTTYPE_TO_STRLEN(pid_t) + STRLITERALLEN(" ") + LXC_IDMAPLEN] = {0}; bool had_entry = false, maps_host_root = false, use_shadow = false; - int hostuid, hostgid; hostuid = geteuid(); hostgid = getegid(); @@ -3595,10 +3591,9 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid) /* Check if we really need to use newuidmap and newgidmap. * If the user is only remapping their own {g,u}id, we don't need it. */ - if (use_shadow && lxc_list_len(idmap) == 2) { + if (use_shadow && list_len(idmap) == 2) { use_shadow = false; - lxc_list_for_each(iterator, idmap) { - map = iterator->elem; + list_for_each_entry(map, idmap, head) { if (map->idtype == ID_TYPE_UID && map->range == 1 && map->nsid == hostuid && map->hostid == hostuid) continue; @@ -3617,8 +3612,7 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid) if (use_shadow) pos += sprintf(mapbuf, "new%cidmap %d", u_or_g, pid); - lxc_list_for_each(iterator, idmap) { - map = iterator->elem; + list_for_each_entry(map, idmap, head) { if (map->idtype != type) continue; @@ -3672,15 +3666,13 @@ static id_t get_mapped_rootid(const struct lxc_conf *conf, enum idtype idtype) { unsigned nsid; struct id_map *map; - struct lxc_list *it; if (idtype == ID_TYPE_UID) nsid = (conf->root_nsuid_map != NULL) ? 0 : conf->init_uid; else nsid = (conf->root_nsgid_map != NULL) ? 0 : conf->init_gid; - lxc_list_for_each (it, &conf->id_map) { - map = it->elem; + list_for_each_entry (map, &conf->id_map, head) { if (map->idtype != idtype) continue; if (map->nsid != nsid) @@ -3697,10 +3689,8 @@ static id_t get_mapped_rootid(const struct lxc_conf *conf, enum idtype idtype) int mapped_hostid(unsigned id, const struct lxc_conf *conf, enum idtype idtype) { struct id_map *map; - struct lxc_list *it; - lxc_list_for_each (it, &conf->id_map) { - map = it->elem; + list_for_each_entry(map, &conf->id_map, head) { if (map->idtype != idtype) continue; @@ -3714,12 +3704,10 @@ int mapped_hostid(unsigned id, const struct lxc_conf *conf, enum idtype idtype) int find_unmapped_nsid(const struct lxc_conf *conf, enum idtype idtype) { struct id_map *map; - struct lxc_list *it; unsigned int freeid = 0; again: - lxc_list_for_each (it, &conf->id_map) { - map = it->elem; + list_for_each_entry(map, &conf->id_map, head) { if (map->idtype != idtype) continue; @@ -4071,7 +4059,7 @@ static int lxc_rootfs_prepare_child(struct lxc_handler *handler) int dfd_idmapped = -EBADF; int ret; - if (lxc_list_empty(&handler->conf->id_map)) + if (list_empty(&handler->conf->id_map)) return 0; if (is_empty_string(rootfs->mnt_opts.userns_path)) @@ -4487,27 +4475,25 @@ int lxc_clear_config_caps(struct lxc_conf *c) return 0; } -static int lxc_free_idmap(struct lxc_list *id_map) +static int lxc_free_idmap(struct list_head *id_map) { - struct lxc_list *it, *next; + struct id_map *map, *nmap; - lxc_list_for_each_safe(it, id_map, next) { - lxc_list_del(it); - free(it->elem); - free(it); + list_for_each_entry_safe(map, nmap, id_map, head) { + list_del(&map->head); + free(map); } - lxc_list_init(id_map); + INIT_LIST_HEAD(id_map); return 0; } -static int __lxc_free_idmap(struct lxc_list *id_map) +static int __lxc_free_idmap(struct list_head *id_map) { lxc_free_idmap(id_map); - free(id_map); return 0; } -define_cleanup_function(struct lxc_list *, __lxc_free_idmap); +define_cleanup_function(struct list_head *, __lxc_free_idmap); int lxc_clear_idmaps(struct lxc_conf *c) { @@ -4905,15 +4891,13 @@ static struct id_map *mapped_nsid_add(const struct lxc_conf *conf, unsigned id, return retmap; } -static struct id_map *find_mapped_hostid_entry(const struct lxc_list *idmap, +static struct id_map *find_mapped_hostid_entry(const struct list_head *idmap, unsigned id, enum idtype idtype) { - struct id_map *map; - struct lxc_list *it; struct id_map *retmap = NULL; + struct id_map *map; - lxc_list_for_each (it, idmap) { - map = it->elem; + list_for_each_entry(map, idmap, head) { if (map->idtype != idtype) continue; @@ -4959,22 +4943,20 @@ static struct id_map *mapped_hostid_add(const struct lxc_conf *conf, uid_t id, return move_ptr(entry); } -static struct lxc_list *get_minimal_idmap(const struct lxc_conf *conf, - uid_t *resuid, gid_t *resgid) +static int get_minimal_idmap(const struct lxc_conf *conf, uid_t *resuid, + gid_t *resgid, struct list_head *head_ret) { __do_free struct id_map *container_root_uid = NULL, *container_root_gid = NULL, *host_uid_map = NULL, *host_gid_map = NULL; - __do_free struct lxc_list *idmap = NULL; uid_t euid, egid; uid_t nsuid = (conf->root_nsuid_map != NULL) ? 0 : conf->init_uid; gid_t nsgid = (conf->root_nsgid_map != NULL) ? 0 : conf->init_gid; - struct lxc_list *tmplist = NULL; /* Find container root mappings. */ container_root_uid = mapped_nsid_add(conf, nsuid, ID_TYPE_UID); if (!container_root_uid) - return log_debug(NULL, "Failed to find mapping for namespace uid %d", 0); + return sysdebug("Failed to find mapping for namespace uid %d", 0); euid = geteuid(); if (euid >= container_root_uid->hostid && euid < (container_root_uid->hostid + container_root_uid->range)) @@ -4982,7 +4964,7 @@ static struct lxc_list *get_minimal_idmap(const struct lxc_conf *conf, container_root_gid = mapped_nsid_add(conf, nsgid, ID_TYPE_GID); if (!container_root_gid) - return log_debug(NULL, "Failed to find mapping for namespace gid %d", 0); + return sysdebug("Failed to find mapping for namespace gid %d", 0); egid = getegid(); if (egid >= container_root_gid->hostid && egid < (container_root_gid->hostid + container_root_gid->range)) @@ -4992,50 +4974,31 @@ static struct lxc_list *get_minimal_idmap(const struct lxc_conf *conf, if (!host_uid_map) host_uid_map = mapped_hostid_add(conf, euid, ID_TYPE_UID); if (!host_uid_map) - return log_debug(NULL, "Failed to find mapping for uid %d", euid); + return sysdebug("Failed to find mapping for uid %d", euid); if (!host_gid_map) host_gid_map = mapped_hostid_add(conf, egid, ID_TYPE_GID); if (!host_gid_map) - return log_debug(NULL, "Failed to find mapping for gid %d", egid); + return sysdebug("Failed to find mapping for gid %d", egid); - /* Allocate new {g,u}id map list. */ - idmap = lxc_list_new(); - if (!idmap) - return NULL; - - /* Add container root to the map. */ - tmplist = lxc_list_new(); - if (!tmplist) - return NULL; /* idmap will now keep track of that memory. */ - lxc_list_add_elem(tmplist, move_ptr(host_uid_map)); - lxc_list_add_tail(idmap, tmplist); + list_add_tail(&host_uid_map->head, head_ret); + move_ptr(host_uid_map); if (container_root_uid) { - /* Add container root to the map. */ - tmplist = lxc_list_new(); - if (!tmplist) - return NULL; /* idmap will now keep track of that memory. */ - lxc_list_add_elem(tmplist, move_ptr(container_root_uid)); - lxc_list_add_tail(idmap, tmplist); + list_add_tail(&container_root_uid->head, head_ret); + move_ptr(container_root_uid); } - tmplist = lxc_list_new(); - if (!tmplist) - return NULL; /* idmap will now keep track of that memory. */ - lxc_list_add_elem(tmplist, move_ptr(host_gid_map)); - lxc_list_add_tail(idmap, tmplist); + list_add_tail(&host_gid_map->head, head_ret); + move_ptr(host_gid_map); if (container_root_gid) { - tmplist = lxc_list_new(); - if (!tmplist) - return NULL; /* idmap will now keep track of that memory. */ - lxc_list_add_elem(tmplist, move_ptr(container_root_gid)); - lxc_list_add_tail(idmap, tmplist); + list_add_tail(&container_root_gid->head, head_ret); + move_ptr(container_root_gid); } TRACE("Allocated minimal idmapping for ns uid %d and ns gid %d", nsuid, nsgid); @@ -5044,7 +5007,8 @@ static struct lxc_list *get_minimal_idmap(const struct lxc_conf *conf, *resuid = nsuid; if (resgid) *resgid = nsgid; - return move_ptr(idmap); + + return 0; } /* @@ -5062,7 +5026,8 @@ static struct lxc_list *get_minimal_idmap(const struct lxc_conf *conf, int userns_exec_1(const struct lxc_conf *conf, int (*fn)(void *), void *data, const char *fn_name) { - call_cleaner(__lxc_free_idmap) struct lxc_list *idmap = NULL; + LIST_HEAD(minimal_idmap); + call_cleaner(__lxc_free_idmap) struct list_head *idmap = &minimal_idmap; int ret = -1, status = -1; char c = '1'; struct userns_fn_data d = { @@ -5076,8 +5041,8 @@ int userns_exec_1(const struct lxc_conf *conf, int (*fn)(void *), void *data, if (!conf) return -EINVAL; - idmap = get_minimal_idmap(conf, NULL, NULL); - if (!idmap) + ret = get_minimal_idmap(conf, NULL, NULL, idmap); + if (ret) return ret_errno(ENOENT); ret = pipe2(pipe_fds, O_CLOEXEC); @@ -5098,13 +5063,10 @@ int userns_exec_1(const struct lxc_conf *conf, int (*fn)(void *), void *data, if (lxc_log_trace()) { struct id_map *map; - struct lxc_list *it; - lxc_list_for_each(it, idmap) { - map = it->elem; + list_for_each_entry(map, idmap, head) TRACE("Establishing %cid mapping for \"%d\" in new user namespace: nsuid %lu - hostid %lu - range %lu", (map->idtype == ID_TYPE_UID) ? 'u' : 'g', pid, map->nsid, map->hostid, map->range); - } } /* Set up {g,u}id mapping for user namespace of child process. */ @@ -5138,7 +5100,8 @@ int userns_exec_minimal(const struct lxc_conf *conf, int (*fn_parent)(void *), void *fn_parent_data, int (*fn_child)(void *), void *fn_child_data) { - call_cleaner(__lxc_free_idmap) struct lxc_list *idmap = NULL; + LIST_HEAD(minimal_idmap); + call_cleaner(__lxc_free_idmap) struct list_head *idmap = &minimal_idmap; uid_t resuid = LXC_INVALID_UID; gid_t resgid = LXC_INVALID_GID; char c = '1'; @@ -5149,8 +5112,8 @@ int userns_exec_minimal(const struct lxc_conf *conf, if (!conf || !fn_child) return ret_errno(EINVAL); - idmap = get_minimal_idmap(conf, &resuid, &resgid); - if (!idmap) + ret = get_minimal_idmap(conf, &resuid, &resgid, idmap); + if (ret) return ret_errno(ENOENT); ret = socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, sock_fds); @@ -5212,13 +5175,10 @@ int userns_exec_minimal(const struct lxc_conf *conf, if (lxc_log_trace()) { struct id_map *map; - struct lxc_list *it; - lxc_list_for_each(it, idmap) { - map = it->elem; + list_for_each_entry(map, idmap, head) TRACE("Establishing %cid mapping for \"%d\" in new user namespace: nsuid %lu - hostid %lu - range %lu", (map->idtype == ID_TYPE_UID) ? 'u' : 'g', pid, map->nsid, map->hostid, map->range); - } } ret = lxc_read_nointr(sock_fds[1], &c, 1); @@ -5260,26 +5220,24 @@ on_error: int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *), void *data, const char *fn_name) { + LIST_HEAD(full_idmap); + int ret = -1; + char c = '1'; + struct id_map *container_root_uid = NULL, *container_root_gid = NULL, + *host_uid_map = NULL, *host_gid_map = NULL; pid_t pid; uid_t euid, egid; int p[2]; struct id_map *map; - struct lxc_list *cur; struct userns_fn_data d; - int ret = -1; - char c = '1'; - struct lxc_list *idmap = NULL, *tmplist = NULL; - struct id_map *container_root_uid = NULL, *container_root_gid = NULL, - *host_uid_map = NULL, *host_gid_map = NULL; if (!conf) return -EINVAL; ret = pipe2(p, O_CLOEXEC); - if (ret < 0) { - SYSERROR("opening pipe"); - return -1; - } + if (ret < 0) + return -errno; + d.fn = fn; d.fn_name = fn_name; d.arg = data; @@ -5299,32 +5257,16 @@ int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *), void *data, euid = geteuid(); egid = getegid(); - /* Allocate new {g,u}id map list. */ - idmap = lxc_list_new(); - if (!idmap) - goto on_error; - /* Find container root. */ - lxc_list_for_each (cur, &conf->id_map) { - struct id_map *tmpmap; + list_for_each_entry(map, &conf->id_map, head) { + __do_free struct id_map *dup_map = NULL; - tmplist = lxc_list_new(); - if (!tmplist) + dup_map = memdup(map, sizeof(struct id_map)); + if (!dup_map) goto on_error; - tmpmap = zalloc(sizeof(*tmpmap)); - if (!tmpmap) { - free(tmplist); - goto on_error; - } - - memset(tmpmap, 0, sizeof(*tmpmap)); - memcpy(tmpmap, cur->elem, sizeof(*tmpmap)); - tmplist->elem = tmpmap; - - lxc_list_add_tail(idmap, tmplist); - - map = cur->elem; + list_add_tail(&dup_map->head, &full_idmap); + move_ptr(dup_map); if (map->idtype == ID_TYPE_UID) if (euid >= map->hostid && euid < map->hostid + map->range) @@ -5373,39 +5315,27 @@ int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *), void *data, } if (host_uid_map && (host_uid_map != container_root_uid)) { - /* Add container root to the map. */ - tmplist = lxc_list_new(); - if (!tmplist) - goto on_error; - lxc_list_add_elem(tmplist, host_uid_map); - lxc_list_add_tail(idmap, tmplist); + /* idmap will now keep track of that memory. */ + list_add_tail(&host_uid_map->head, &full_idmap); + move_ptr(host_uid_map); } - /* idmap will now keep track of that memory. */ - host_uid_map = NULL; if (host_gid_map && (host_gid_map != container_root_gid)) { - tmplist = lxc_list_new(); - if (!tmplist) - goto on_error; - lxc_list_add_elem(tmplist, host_gid_map); - lxc_list_add_tail(idmap, tmplist); + /* idmap will now keep track of that memory. */ + list_add_tail(&host_gid_map->head, &full_idmap); + move_ptr(host_gid_map); } - /* idmap will now keep track of that memory. */ - host_gid_map = NULL; if (lxc_log_trace()) { - lxc_list_for_each (cur, idmap) { - map = cur->elem; - TRACE("establishing %cid mapping for \"%d\" in new " - "user namespace: nsuid %lu - hostid %lu - range " - "%lu", + list_for_each_entry(map, &full_idmap, head) { + TRACE("establishing %cid mapping for \"%d\" in new user namespace: nsuid %lu - hostid %lu - range %lu", (map->idtype == ID_TYPE_UID) ? 'u' : 'g', pid, map->nsid, map->hostid, map->range); } } /* Set up {g,u}id mapping for user namespace of child process. */ - ret = lxc_map_ids(idmap, pid); + ret = lxc_map_ids(&full_idmap, pid); if (ret < 0) { ERROR("error setting up {g,u}id mappings for child process \"%d\"", pid); goto on_error; @@ -5426,8 +5356,7 @@ on_error: if (pid > 0) ret = wait_for_pid(pid); - if (idmap) - __lxc_free_idmap(idmap); + __lxc_free_idmap(&full_idmap); if (host_uid_map && (host_uid_map != container_root_uid)) free(host_uid_map); @@ -5437,12 +5366,11 @@ on_error: return ret; } -static int add_idmap_entry(struct lxc_list *idmap, enum idtype idtype, +static int add_idmap_entry(struct list_head *idmap_list, enum idtype idtype, unsigned long nsid, unsigned long hostid, unsigned long range) { __do_free struct id_map *new_idmap = NULL; - __do_free struct lxc_list *new_list = NULL; new_idmap = zalloc(sizeof(*new_idmap)); if (!new_idmap) @@ -5453,12 +5381,8 @@ static int add_idmap_entry(struct lxc_list *idmap, enum idtype idtype, new_idmap->nsid = nsid; new_idmap->range = range; - new_list = zalloc(sizeof(*new_list)); - if (!new_list) - return ret_errno(ENOMEM); - - new_list->elem = move_ptr(new_idmap); - lxc_list_add_tail(idmap, move_ptr(new_list)); + list_add_tail(&new_idmap->head, idmap_list); + move_ptr(new_idmap); INFO("Adding id map: type %c nsid %lu hostid %lu range %lu", idtype == ID_TYPE_UID ? 'u' : 'g', nsid, hostid, range); @@ -5468,7 +5392,8 @@ static int add_idmap_entry(struct lxc_list *idmap, enum idtype idtype, int userns_exec_mapped_root(const char *path, int path_fd, const struct lxc_conf *conf) { - call_cleaner(__lxc_free_idmap) struct lxc_list *idmap = NULL; + LIST_HEAD(idmap_list); + call_cleaner(__lxc_free_idmap) struct list_head *idmap = &idmap_list; __do_close int fd = -EBADF; int target_fd = -EBADF; char c = '1'; @@ -5534,10 +5459,6 @@ int userns_exec_mapped_root(const char *path, int path_fd, TRACE("Chowned %d(%s) to -1:%d", target_fd, path, hostgid); } - idmap = lxc_list_new(); - if (!idmap) - return -ENOMEM; - /* "u:0:rootuid:1" */ ret = add_idmap_entry(idmap, ID_TYPE_UID, 0, container_host_uid, 1); if (ret < 0) @@ -5615,13 +5536,10 @@ int userns_exec_mapped_root(const char *path, int path_fd, if (lxc_log_trace()) { struct id_map *map; - struct lxc_list *it; - lxc_list_for_each(it, idmap) { - map = it->elem; + list_for_each_entry(map, idmap, head) TRACE("Establishing %cid mapping for \"%d\" in new user namespace: nsuid %lu - hostid %lu - range %lu", (map->idtype == ID_TYPE_UID) ? 'u' : 'g', pid, map->nsid, map->hostid, map->range); - } } ret = lxc_read_nointr(sock_fds[1], &c, 1); diff --git a/src/lxc/conf.h b/src/lxc/conf.h index e8d776cdc..5965e9e3d 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -181,6 +181,7 @@ define_cleanup_function(struct lxc_proc *, free_lxc_proc); struct id_map { enum idtype idtype; unsigned long hostid, nsid, range; + struct list_head head; }; /* Defines the number of tty configured and contains the @@ -352,7 +353,7 @@ struct lxc_conf { }; struct { - struct lxc_list id_map; + struct list_head id_map; /* * Pointer to the idmap entry for the container's root uid in @@ -525,7 +526,7 @@ __hidden extern void lxc_storage_put(struct lxc_conf *conf); __hidden extern int lxc_rootfs_init(struct lxc_conf *conf, bool userns); __hidden extern int lxc_rootfs_prepare_parent(struct lxc_handler *handler); __hidden extern int lxc_idmapped_mounts_parent(struct lxc_handler *handler); -__hidden extern int lxc_map_ids(struct lxc_list *idmap, pid_t pid); +__hidden extern int lxc_map_ids(struct list_head *idmap, pid_t pid); __hidden extern int lxc_create_tty(const char *name, struct lxc_conf *conf); __hidden extern void lxc_delete_tty(struct lxc_tty_info *ttys); __hidden extern int lxc_clear_config_caps(struct lxc_conf *c); diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 513b917d9..d9d3e45df 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -2210,7 +2210,6 @@ static int set_config_proc(const char *key, const char *value, static int set_config_idmaps(const char *key, const char *value, struct lxc_conf *lxc_conf, void *data) { - __do_free struct lxc_list *idmaplist = NULL; __do_free struct id_map *idmap = NULL; unsigned long hostid, nsid, range; char type; @@ -2219,10 +2218,6 @@ static int set_config_idmaps(const char *key, const char *value, if (lxc_config_value_empty(value)) return lxc_clear_idmaps(lxc_conf); - idmaplist = lxc_list_new(); - if (!idmaplist) - return ret_errno(ENOMEM); - idmap = zalloc(sizeof(*idmap)); if (!idmap) return ret_errno(ENOMEM); @@ -2242,8 +2237,7 @@ static int set_config_idmaps(const char *key, const char *value, idmap->hostid = hostid; idmap->nsid = nsid; idmap->range = range; - idmaplist->elem = idmap; - lxc_list_add_tail(&lxc_conf->id_map, idmaplist); + list_add_tail(&idmap->head, &lxc_conf->id_map); if (!lxc_conf->root_nsuid_map && idmap->idtype == ID_TYPE_UID) if (idmap->nsid == 0) @@ -2254,7 +2248,6 @@ static int set_config_idmaps(const char *key, const char *value, lxc_conf->root_nsgid_map = idmap; move_ptr(idmap); - move_ptr(idmaplist); return 0; } @@ -3996,7 +3989,7 @@ static inline int get_config_cgroup_relative(const char *key, char *retv, static int get_config_idmaps(const char *key, char *retv, int inlen, struct lxc_conf *c, void *data) { - struct lxc_list *it; + struct id_map *map; int len, listlen, ret; int fulllen = 0; /* "u 1000 1000000 65536" @@ -4027,9 +4020,8 @@ static int get_config_idmaps(const char *key, char *retv, int inlen, else memset(retv, 0, inlen); - listlen = lxc_list_len(&c->id_map); - lxc_list_for_each(it, &c->id_map) { - struct id_map *map = it->elem; + listlen = list_len(&c->id_map); + list_for_each_entry(map, &c->id_map, head) { ret = strnprintf(buf, sizeof(buf), "%c %lu %lu %lu", (map->idtype == ID_TYPE_UID) ? 'u' : 'g', map->nsid, map->hostid, map->range); diff --git a/src/lxc/lsm/apparmor.c b/src/lxc/lsm/apparmor.c index a0d81ea01..63d122591 100644 --- a/src/lxc/lsm/apparmor.c +++ b/src/lxc/lsm/apparmor.c @@ -668,7 +668,7 @@ static void must_append_sized(char **buf, size_t *bufsz, const char *data, size_ static bool is_privileged(struct lxc_conf *conf) { - return lxc_list_empty(&conf->id_map); + return list_empty(&conf->id_map); } static const char* AA_ALL_DEST_PATH_LIST[] = { diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 96c3ee31b..fea073f14 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -1219,7 +1219,7 @@ static int do_create_container_dir(const char *path, struct lxc_conf *conf) ret = 0; } - if (!lxc_list_empty(&conf->id_map)) { + if (!list_empty(&conf->id_map)) { ret = chown_mapped_root(path, conf); if (ret < 0) ret = -1; @@ -1290,7 +1290,7 @@ static struct lxc_storage *do_storage_create(struct lxc_container *c, /* If we are not root, chown the rootfs dir to root in the target user * namespace. */ - if (am_guest_unpriv() || !lxc_list_empty(&c->lxc_conf->id_map)) { + if (am_guest_unpriv() || !list_empty(&c->lxc_conf->id_map)) { ret = chown_mapped_root(bdev->dest, c->lxc_conf); if (ret < 0) { ERROR("Error chowning \"%s\" to container root", bdev->dest); @@ -1482,11 +1482,10 @@ static bool create_run_template(struct lxc_container *c, char *tpath, * ... <-m mapn> -- and we append "--mapped-uid x", where x is * the mapped uid for our geteuid() */ - if (!lxc_list_empty(&conf->id_map)) { + if (!list_empty(&conf->id_map)) { int extraargs, hostuid_mapped, hostgid_mapped; char **n2; char txtuid[20], txtgid[20]; - struct lxc_list *it; struct id_map *map; int n2args = 1; @@ -1498,8 +1497,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, tpath = "lxc-usernsexec"; n2[0] = "lxc-usernsexec"; - lxc_list_for_each(it, &conf->id_map) { - map = it->elem; + list_for_each_entry(map, &conf->id_map, head) { n2args += 2; n2 = realloc(n2, n2args * sizeof(char *)); if (!n2) @@ -2239,7 +2237,7 @@ static inline bool enter_net_ns(struct lxc_container *c) if (pid < 0) return false; - if ((geteuid() != 0 || (c->lxc_conf && !lxc_list_empty(&c->lxc_conf->id_map))) && + if ((geteuid() != 0 || (c->lxc_conf && !list_empty(&c->lxc_conf->id_map))) && (access("/proc/self/ns/user", F_OK) == 0)) if (!switch_to_ns(pid, "user")) return false; @@ -5077,7 +5075,7 @@ static int do_lxcapi_mount(struct lxc_container *c, const char *source, } /* Enter the container namespaces */ - if (!lxc_list_empty(&c->lxc_conf->id_map)) { + if (!list_empty(&c->lxc_conf->id_map)) { if (!switch_to_ns(init_pid, "user")) { ERROR("Failed to enter user namespace"); _exit(EXIT_FAILURE); @@ -5170,7 +5168,7 @@ static int do_lxcapi_umount(struct lxc_container *c, const char *target, } /* Enter the container namespaces */ - if (!lxc_list_empty(&c->lxc_conf->id_map)) { + if (!list_empty(&c->lxc_conf->id_map)) { if (!switch_to_ns(init_pid, "user")) { ERROR("Failed to enter user namespace"); _exit(EXIT_FAILURE); diff --git a/src/lxc/start.c b/src/lxc/start.c index 4f09e4e5c..7041a913c 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -1110,7 +1110,7 @@ static int do_start(void *data) /* If we are in a new user namespace, become root there to have * privilege over our namespace. */ - if (!lxc_list_empty(&handler->conf->id_map)) { + if (!list_empty(&handler->conf->id_map)) { if (!handler->conf->root_nsuid_map) nsuid = handler->conf->init_uid; @@ -1406,7 +1406,7 @@ static int do_start(void *data) * we switched to root in the new user namespace further above. Only * drop groups if we can, so ensure that we have necessary privilege. */ - if (lxc_list_empty(&handler->conf->id_map)) { + if (list_empty(&handler->conf->id_map)) { #if HAVE_LIBCAP if (lxc_proc_cap_is_set(CAP_SETGID, CAP_EFFECTIVE)) #endif @@ -1473,7 +1473,7 @@ int resolve_clone_flags(struct lxc_handler *handler) if ((conf->ns_clone & ns_info[i].clone_flag)) handler->ns_clone_flags |= ns_info[i].clone_flag; } else { - if (i == LXC_NS_USER && lxc_list_empty(&handler->conf->id_map)) + if (i == LXC_NS_USER && list_empty(&handler->conf->id_map)) continue; if (i == LXC_NS_NET && lxc_requests_empty_network(handler)) @@ -1576,7 +1576,7 @@ static int lxc_spawn(struct lxc_handler *handler) int i, ret; char pidstr[20]; bool wants_to_map_ids; - struct lxc_list *id_map; + struct list_head *id_map; const char *name = handler->name; const char *lxcpath = handler->lxcpath; bool share_ns = false; @@ -1584,7 +1584,7 @@ static int lxc_spawn(struct lxc_handler *handler) struct cgroup_ops *cgroup_ops = handler->cgroup_ops; id_map = &conf->id_map; - wants_to_map_ids = !lxc_list_empty(id_map); + wants_to_map_ids = !list_empty(id_map); for (i = 0; i < LXC_NS_MAX; i++) { if (!conf->ns_share[i]) @@ -2012,14 +2012,14 @@ int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops, * it readonly. * If the container is unprivileged then skip rootfs pinning. */ - ret = lxc_rootfs_init(conf, !lxc_list_empty(&conf->id_map)); + ret = lxc_rootfs_init(conf, !list_empty(&conf->id_map)); if (ret) { ERROR("Failed to handle rootfs pinning for container \"%s\"", handler->name); ret = -1; goto out_abort; } - if (geteuid() == 0 && !lxc_list_empty(&conf->id_map)) { + if (geteuid() == 0 && !list_empty(&conf->id_map)) { /* * Most filesystems can't be mounted inside a userns so handle them here. */ diff --git a/src/lxc/storage/overlay.c b/src/lxc/storage/overlay.c index 8fe523973..1479a9ce8 100644 --- a/src/lxc/storage/overlay.c +++ b/src/lxc/storage/overlay.c @@ -57,7 +57,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char return -1; } - if (am_guest_unpriv() || !lxc_list_empty(&conf->id_map)) { + if (am_guest_unpriv() || !list_empty(&conf->id_map)) { ret = chown_mapped_root(new->dest, conf); if (ret < 0) WARN("Failed to update ownership of %s", new->dest); @@ -88,7 +88,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char if (ret < 0 && errno != EEXIST) return log_error_errno(-errno, errno, "Failed to create directory \"%s\"", work); - if (am_guest_unpriv() || !lxc_list_empty(&conf->id_map)) { + if (am_guest_unpriv() || !list_empty(&conf->id_map)) { __do_free char *lxc_overlay_delta_dir = NULL, *lxc_overlay_private_dir = NULL; @@ -155,7 +155,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char if (ret < 0 && errno != EEXIST) return log_error_errno(-errno, errno, "Failed to create directory \"%s\"", ndelta); - if (am_guest_unpriv() || !lxc_list_empty(&conf->id_map)) { + if (am_guest_unpriv() || !list_empty(&conf->id_map)) { __do_free char *lxc_overlay_delta_dir = NULL, *lxc_overlay_private_dir = NULL; @@ -276,7 +276,7 @@ int ovl_create(struct lxc_storage *bdev, const char *dest, const char *n, if (ret < 0 && errno != EEXIST) return log_error_errno(-errno, errno, "Failed to create directory \"%s\"", delta); - if (am_guest_unpriv() || !lxc_list_empty(&conf->id_map)) { + if (am_guest_unpriv() || !list_empty(&conf->id_map)) { __do_free char *lxc_overlay_private_dir = NULL; lxc_overlay_private_dir = must_make_path(tmp, LXC_OVERLAY_PRIVATE_DIR, NULL); diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c index da5748748..7327893b3 100644 --- a/src/lxc/terminal.c +++ b/src/lxc/terminal.c @@ -876,7 +876,7 @@ static int lxc_terminal_map_ids(struct lxc_conf *c, struct lxc_terminal *termina { int ret; - if (lxc_list_empty(&c->id_map)) + if (list_empty(&c->id_map)) return 0; if (is_empty_string(terminal->name) && terminal->pty < 0)