From: Christian Brauner Date: Sun, 28 May 2017 13:10:35 +0000 (+0200) Subject: conf: rework lxc_map_ids() X-Git-Tag: lxc-2.1.0~108^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=986ef93023ba797a658a57bc9350250d9ebdecb7;p=thirdparty%2Flxc.git conf: rework lxc_map_ids() Especially, in case the new{g,u}idmap is used we should try to gather std{err,out} on error to better debug what is going on. Signed-off-by: Christian Brauner --- diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 0efd70c94..35501ee4d 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -3473,16 +3473,35 @@ cleanup: return fret; } +int lxc_map_ids_exec_wrapper(void *args) +{ + execl("/bin/sh", "sh", "-c", (char *)args, (char *)NULL); + return -1; +} + int lxc_map_ids(struct lxc_list *idmap, pid_t pid) { struct id_map *map; struct lxc_list *iterator; enum idtype type; + char u_or_g; char *pos; - int euid; - int ret = 0, use_shadow = 0; - int uidmap = 0, gidmap = 0; - char *buf = NULL; + int euid, fill, left; + char cmd_output[MAXPATHLEN]; + /* strlen("new@idmap") = 9 + * + + * strlen(" ") = 1 + * + + * LXC_NUMSTRLEN64 + * + + * strlen(" ") = 1 + * + * We add some additional space to make sure that we really have + * LXC_IDMAPLEN bytes available for our the {g,u]id mapping. + */ + char mapbuf[9 + 1 + LXC_NUMSTRLEN64 + 1 + LXC_IDMAPLEN] = {0}; + int ret = 0, uidmap = 0, gidmap = 0; + bool use_shadow = false, had_entry = false; euid = geteuid(); @@ -3507,17 +3526,12 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid) return -1; } - for (type = ID_TYPE_UID; type <= ID_TYPE_GID; type++) { - int left, fill; - bool had_entry = false; - if (!buf) { - buf = pos = malloc(LXC_IDMAPLEN); - if (!buf) - return -ENOMEM; - } - pos = buf; + for (type = ID_TYPE_UID, u_or_g = 'u'; type <= ID_TYPE_GID; + type++, u_or_g = 'g') { + pos = mapbuf; + if (use_shadow) - pos += sprintf(buf, "new%cidmap %d", type == ID_TYPE_UID ? 'u' : 'g', pid); + pos += sprintf(mapbuf, "new%cidmap %d", u_or_g, pid); lxc_list_for_each(iterator, idmap) { /* The kernel only takes <= 4k for writes to @@ -3529,7 +3543,7 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid) had_entry = true; - left = LXC_IDMAPLEN - (pos - buf); + left = LXC_IDMAPLEN - (pos - mapbuf); fill = snprintf(pos, left, "%s%lu %lu %lu%s", use_shadow ? " " : "", map->nsid, map->hostid, map->range, @@ -3542,22 +3556,28 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid) if (!had_entry) continue; - if (!use_shadow) { - ret = write_id_mapping(type, pid, buf, pos - buf); + /* Try to catch the ouput of new{g,u}idmap to make debugging + * easier. + */ + if (use_shadow) { + ret = run_command(cmd_output, sizeof(cmd_output), + lxc_map_ids_exec_wrapper, + (void *)mapbuf); + if (ret < 0) { + ERROR("new%cidmap failed to write mapping: %s", + u_or_g, cmd_output); + return -1; + } } else { - left = LXC_IDMAPLEN - (pos - buf); - fill = snprintf(pos, left, "\n"); - if (fill <= 0 || fill >= left) - SYSERROR("Too many {g,u}id mappings defined."); - pos += fill; - ret = system(buf); + ret = write_id_mapping(type, pid, mapbuf, pos - mapbuf); + if (ret < 0) + return -1; } - if (ret) - break; + + memset(mapbuf, 0, sizeof(mapbuf)); } - free(buf); - return ret; + return 0; } /*