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: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent ea3a694f
...@@ -3473,16 +3473,35 @@ cleanup: ...@@ -3473,16 +3473,35 @@ cleanup:
return fret; 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) int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
{ {
struct id_map *map; struct id_map *map;
struct lxc_list *iterator; struct lxc_list *iterator;
enum idtype type; enum idtype type;
char u_or_g;
char *pos; char *pos;
int euid; int euid, fill, left;
int ret = 0, use_shadow = 0; char cmd_output[MAXPATHLEN];
int uidmap = 0, gidmap = 0; /* strlen("new@idmap") = 9
char *buf = NULL; * +
* 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(); euid = geteuid();
...@@ -3507,17 +3526,12 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid) ...@@ -3507,17 +3526,12 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
return -1; return -1;
} }
for (type = ID_TYPE_UID; type <= ID_TYPE_GID; type++) { for (type = ID_TYPE_UID, u_or_g = 'u'; type <= ID_TYPE_GID;
int left, fill; type++, u_or_g = 'g') {
bool had_entry = false; pos = mapbuf;
if (!buf) {
buf = pos = malloc(LXC_IDMAPLEN);
if (!buf)
return -ENOMEM;
}
pos = buf;
if (use_shadow) 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) { lxc_list_for_each(iterator, idmap) {
/* The kernel only takes <= 4k for writes to /* The kernel only takes <= 4k for writes to
...@@ -3529,7 +3543,7 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid) ...@@ -3529,7 +3543,7 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
had_entry = true; had_entry = true;
left = LXC_IDMAPLEN - (pos - buf); left = LXC_IDMAPLEN - (pos - mapbuf);
fill = snprintf(pos, left, "%s%lu %lu %lu%s", fill = snprintf(pos, left, "%s%lu %lu %lu%s",
use_shadow ? " " : "", map->nsid, use_shadow ? " " : "", map->nsid,
map->hostid, map->range, map->hostid, map->range,
...@@ -3542,22 +3556,28 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid) ...@@ -3542,22 +3556,28 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
if (!had_entry) if (!had_entry)
continue; continue;
if (!use_shadow) { /* Try to catch the ouput of new{g,u}idmap to make debugging
ret = write_id_mapping(type, pid, buf, pos - buf); * 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 { } else {
left = LXC_IDMAPLEN - (pos - buf); ret = write_id_mapping(type, pid, mapbuf, pos - mapbuf);
fill = snprintf(pos, left, "\n"); if (ret < 0)
if (fill <= 0 || fill >= left) return -1;
SYSERROR("Too many {g,u}id mappings defined.");
pos += fill;
ret = system(buf);
} }
if (ret)
break; memset(mapbuf, 0, sizeof(mapbuf));
} }
free(buf); return 0;
return ret;
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment