The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/1609
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Signed-off-by: Christian Brauner <[email protected]>
From 9d03851990dccf216c2b40afe0ecaea2e71ad301 Mon Sep 17 00:00:00 2001 From: Christian Brauner <[email protected]> Date: Thu, 1 Jun 2017 23:43:16 +0200 Subject: [PATCH 1/2] confile: move idmap parser to separate helper Signed-off-by: Christian Brauner <[email protected]> --- src/lxc/confile.c | 178 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 101 insertions(+), 77 deletions(-) diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 4186d6347..ee15690e7 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -1979,131 +1979,156 @@ static int set_config_limit(const char *key, const char *value, return -1; } -static int set_config_idmaps(const char *key, const char *value, - struct lxc_conf *lxc_conf) +static int parse_idmaps(const char *idmap, char *type, unsigned long *nsid, + unsigned long *hostid, unsigned long *range) { - unsigned long hostid, nsid, range; - char type; + int ret = -1; + unsigned long tmp_hostid, tmp_nsid, tmp_range; + char tmp_type; char *window, *slide; char *dup = NULL; - struct lxc_list *idmaplist = NULL; - struct id_map *idmap = NULL; - - if (config_value_empty(value)) - return lxc_clear_idmaps(lxc_conf); - - idmaplist = malloc(sizeof(*idmaplist)); - if (!idmaplist) - goto on_error; - - idmap = malloc(sizeof(*idmap)); - if (!idmap) - goto on_error; - memset(idmap, 0, sizeof(*idmap)); /* Duplicate string. */ - dup = strdup(value); + dup = strdup(idmap); if (!dup) goto on_error; /* A prototypical idmap entry would be: "u 1000 1000000 65536" */ /* align */ - slide = window = dup; - /* skip whitespace */ - slide += strspn(slide, " \t\r"); - if (slide != window && *slide == '\0') - goto on_error; + 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; + if (*slide != 'u' && *slide != 'g') + goto on_error; + /* Assign type. */ + tmp_type = *slide; /* move beyond type */ - slide++; + slide++; /* align */ - window = slide; - /* Validate that only whitespace follows. */ - slide += strspn(slide, " \t\r"); + window = slide; + /* Validate that only whitespace follows. */ + slide += strspn(slide, " \t\r"); /* There must be whitespace. */ - if (slide == window) - goto on_error; + if (slide == window) + goto on_error; - /* Mark beginning of nsuid. */ - window = slide; + /* Mark beginning of nsuid. */ + window = slide; /* Validate that non-whitespace follows. */ - slide += strcspn(slide, " \t\r"); + slide += strcspn(slide, " \t\r"); /* There must be non-whitespace. */ - if (slide == window || *slide == '\0') - goto on_error; - /* Mark end of nsuid. */ - *slide = '\0'; + 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; + /* Parse nsuid. */ + if (lxc_safe_ulong(window, &tmp_nsid) < 0) + goto on_error; /* Move beyond \0. */ - slide++; + slide++; /* align */ - window = slide; - /* Validate that only whitespace follows. */ - slide += strspn(slide, " \t\r"); + 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; + goto on_error; - /* Mark beginning of hostid. */ - window = slide; + /* Mark beginning of hostid. */ + window = slide; /* Validate that non-whitespace follows. */ - slide += strcspn(slide, " \t\r"); + slide += strcspn(slide, " \t\r"); /* There must be non-whitespace. */ - if (slide == window || *slide == '\0') - goto on_error; - /* Mark end of nsuid. */ - *slide = '\0'; + 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; + /* Parse hostid. */ + if (lxc_safe_ulong(window, &tmp_hostid) < 0) + goto on_error; /* Move beyond \0. */ - slide++; + slide++; /* align */ - window = slide; - /* Validate that only whitespace follows. */ - slide += strspn(slide, " \t\r"); + 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; + if (*slide == '\0') + goto on_error; - /* Mark beginning of range. */ - window = slide; + /* Mark beginning of range. */ + window = slide; /* Validate that non-whitespace follows. */ - slide += strcspn(slide, " \t\r"); + slide += strcspn(slide, " \t\r"); /* There must be non-whitespace. */ - if (slide == window) - goto on_error; + 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'; + goto on_error; + /* Mark end of range. */ + *slide = '\0'; + + /* Parse range. */ + if (lxc_safe_ulong(window, &tmp_range) < 0) + goto on_error; - /* Parse range. */ - if (lxc_safe_ulong(window, &range) < 0) - goto on_error; + *type = tmp_type; + *nsid = tmp_nsid; + *hostid = tmp_hostid; + *range = tmp_range; /* Yay, we survived. */ + ret = 0; + +on_error: + free(dup); + + return ret; +} + +static int set_config_idmaps(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + unsigned long hostid, nsid, range; + char type; + int ret; + struct lxc_list *idmaplist = NULL; + struct id_map *idmap = NULL; + + if (config_value_empty(value)) + return lxc_clear_idmaps(lxc_conf); + + idmaplist = malloc(sizeof(*idmaplist)); + if (!idmaplist) + goto on_error; + + idmap = malloc(sizeof(*idmap)); + if (!idmap) + goto on_error; + memset(idmap, 0, sizeof(*idmap)); + + ret = parse_idmaps(value, &type, &nsid, &hostid, &range); + if (ret < 0) + goto on_error; + INFO("read uid map: type %c nsid %lu hostid %lu range %lu", type, nsid, hostid, range); if (type == 'u') idmap->idtype = ID_TYPE_UID; @@ -2124,7 +2149,6 @@ static int set_config_idmaps(const char *key, const char *value, on_error: free(idmaplist); free(idmap); - free(dup); return -1; } From ef019d918762d95bb6ec03a4cbaf3094d2b1bf53 Mon Sep 17 00:00:00 2001 From: Christian Brauner <[email protected]> Date: Thu, 1 Jun 2017 23:43:34 +0200 Subject: [PATCH 2/2] tests: add unit tests for idmap parser Signed-off-by: Christian Brauner <[email protected]> --- src/tests/parse_config_file.c | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/tests/parse_config_file.c b/src/tests/parse_config_file.c index 509370615..1ae145f0c 100644 --- a/src/tests/parse_config_file.c +++ b/src/tests/parse_config_file.c @@ -28,6 +28,7 @@ #include <errno.h> #include <string.h> +#include "confile.c" #include "lxc/state.h" #include "lxctest.h" @@ -103,6 +104,53 @@ static int set_get_compare_clear_save_load(struct lxc_container *c, return 0; } +int test_idmap_parser(void) +{ + size_t i; + struct idmap_check { + bool is_valid; + const char *idmap; + }; + static struct idmap_check idmaps[] = { + /* valid idmaps */ + { true, "u 0 0 0" }, + { true, "g 0 0 0" }, + { true, "u 1000 165536 65536" }, + { true, "g 999 999 1" }, + { true, "u 0 5000 100000" }, + { true, "g 577 789 5" }, + { true, "u 65536 65536 1 " }, + /* invalid idmaps */ + { false, "1u 0 0 0" }, + { false, "1g 0 0 0a" }, + { false, "1 u 0 0 0" }, + { false, "1g 0 0 0 1" }, + { false, "1u a0 b0 c0 d1" }, + { false, "1g 0 b0 0 d1" }, + { false, "1u a0 0 c0 1" }, + { false, "g -1 0 -10" }, + { false, "a 1 0 10" }, + { false, "u 1 1 0 10" }, + { false, "g 1 0 10 z " }, + }; + + for (i = 0; i < sizeof(idmaps) / sizeof(struct idmap_check); i++) { + unsigned long hostid, nsid, range; + char type; + int ret; + ret = parse_idmaps(idmaps[i].idmap, &type, &nsid, &hostid, + &range); + if ((ret < 0 && idmaps[i].is_valid) || + (ret == 0 && !idmaps[i].is_valid)) { + lxc_error("failed to parse idmap \"%s\"\n", + idmaps[i].idmap); + return -1; + } + } + + return 0; +} + int main(int argc, char *argv[]) { struct lxc_container *c; @@ -489,6 +537,11 @@ int main(int argc, char *argv[]) goto non_test_error; } + if (test_idmap_parser() < 0) { + lxc_error("%s\n", "failed to test parser for \"lxc.id_map\""); + goto non_test_error; + } + ret = EXIT_SUCCESS; non_test_error: c->destroy(c);
_______________________________________________ lxc-devel mailing list [email protected] http://lists.linuxcontainers.org/listinfo/lxc-devel
