Unverified Commit 70325efb by Christian Brauner Committed by Stéphane Graber

confile: properly parse lxc.idmap entries

scanf() really isn't appropriate for this. Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent b84663a8
...@@ -1613,61 +1613,149 @@ out: ...@@ -1613,61 +1613,149 @@ out:
static int config_idmap(const char *key, const char *value, struct lxc_conf *lxc_conf) static int config_idmap(const char *key, const char *value, struct lxc_conf *lxc_conf)
{ {
char *token = "lxc.id_map";
char *subkey;
struct lxc_list *idmaplist = NULL;
struct id_map *idmap = NULL;
unsigned long hostid, nsid, range; unsigned long hostid, nsid, range;
char type; char type;
int ret; char *window, *slide;
char *dup = NULL;
struct lxc_list *idmaplist = NULL;
struct id_map *idmap = NULL;
if (config_value_empty(value)) if (config_value_empty(value))
return lxc_clear_idmaps(lxc_conf); return lxc_clear_idmaps(lxc_conf);
subkey = strstr(key, token);
if (!subkey)
return -1;
if (!strlen(subkey))
return -1;
idmaplist = malloc(sizeof(*idmaplist)); idmaplist = malloc(sizeof(*idmaplist));
if (!idmaplist) if (!idmaplist)
goto out; goto on_error;
idmap = malloc(sizeof(*idmap)); idmap = malloc(sizeof(*idmap));
if (!idmap) if (!idmap)
goto out; goto on_error;
memset(idmap, 0, sizeof(*idmap)); memset(idmap, 0, sizeof(*idmap));
ret = sscanf(value, "%c %lu %lu %lu", &type, &nsid, &hostid, &range); /* Duplicate string. */
if (ret != 4) dup = strdup(value);
goto out; if (!dup)
goto on_error;
/* A prototypical idmap entry would be: "0 1000 1000000 65536" */
/* align */
slide = window = dup;
/* skip whitespace */
slide += strspn(slide, " \t\r");
if (slide != window && *slide == '\0')
goto on_error;
/* Validate type. */
if (*slide != 'u' && *slide != 'g')
goto on_error;
/* Assign type. */
type = *slide;
/* move beyond type */
slide++;
/* align */
window = slide;
/* Validate that only whitespace follows. */
slide += strspn(slide, " \t\r");
/* There must be whitespace. */
if (slide == window)
goto on_error;
/* Mark beginning of nsuid. */
window = slide;
/* Validate that non-whitespace follows. */
slide += strcspn(slide, " \t\r");
/* There must be non-whitespace. */
if (slide == window || *slide == '\0')
goto on_error;
/* Mark end of nsuid. */
*slide = '\0';
/* Parse nsuid. */
if (lxc_safe_ulong(window, &nsid) < 0)
goto on_error;
/* Move beyond \0. */
slide++;
/* align */
window = slide;
/* Validate that only whitespace follows. */
slide += strspn(slide, " \t\r");
/* If there was only one whitespace then we whiped it with our \0 above.
* So only ensure that we're not at the end of the string.
*/
if (*slide == '\0')
goto on_error;
/* Mark beginning of hostid. */
window = slide;
/* Validate that non-whitespace follows. */
slide += strcspn(slide, " \t\r");
/* There must be non-whitespace. */
if (slide == window || *slide == '\0')
goto on_error;
/* Mark end of nsuid. */
*slide = '\0';
/* Parse hostid. */
if (lxc_safe_ulong(window, &hostid) < 0)
goto on_error;
/* Move beyond \0. */
slide++;
/* align */
window = slide;
/* Validate that only whitespace follows. */
slide += strspn(slide, " \t\r");
/* If there was only one whitespace then we whiped it with our \0 above.
* So only ensure that we're not at the end of the string.
*/
if (*slide == '\0')
goto on_error;
/* Mark beginning of range. */
window = slide;
/* Validate that non-whitespace follows. */
slide += strcspn(slide, " \t\r");
/* There must be non-whitespace. */
if (slide == window)
goto on_error;
/* The range is the last valid entry we expect. So make sure that there
* is not trailing garbage and if there is, error out.
*/
if (*(slide + strspn(slide, " \t\r\n")) != '\0')
goto on_error;
/* Mark end of range. */
*slide = '\0';
/* Parse range. */
if (lxc_safe_ulong(window, &range) < 0)
goto on_error;
/* Yay, we survived. */
INFO("read uid map: type %c nsid %lu hostid %lu range %lu", type, nsid, hostid, range); INFO("read uid map: type %c nsid %lu hostid %lu range %lu", type, nsid, hostid, range);
if (type == 'u') if (type == 'u')
idmap->idtype = ID_TYPE_UID; idmap->idtype = ID_TYPE_UID;
else if (type == 'g') else if (type == 'g')
idmap->idtype = ID_TYPE_GID; idmap->idtype = ID_TYPE_GID;
else else
goto out; goto on_error;
idmap->hostid = hostid; idmap->hostid = hostid;
idmap->nsid = nsid; idmap->nsid = nsid;
idmap->range = range; idmap->range = range;
idmaplist->elem = idmap; idmaplist->elem = idmap;
lxc_list_add_tail(&lxc_conf->id_map, idmaplist); lxc_list_add_tail(&lxc_conf->id_map, idmaplist);
idmap = NULL;
return 0; return 0;
out: on_error:
free(idmaplist); free(idmaplist);
free(idmap);
if (idmap) { free(dup);
free(idmap);
}
return -1; return -1;
} }
......
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