diff --git a/src/lxc/namespace.c b/src/lxc/namespace.c index 2459c9d2e..b6e3938b1 100644 --- a/src/lxc/namespace.c +++ b/src/lxc/namespace.c @@ -193,6 +193,40 @@ int lxc_namespace_2_ns_idx(const char *namespace) return -EINVAL; } +extern int lxc_namespace_2_std_identifiers(char *namespaces) +{ + char **it; + char *del; + + /* The identifiers for namespaces used with lxc-attach and lxc-unshare + * as given on the manpage do not align with the standard identifiers. + * This affects network, mount, and uts namespaces. The standard identifiers + * are: "mnt", "uts", and "net" whereas lxc-attach and lxc-unshare uses + * "MOUNT", "UTSNAME", and "NETWORK". So let's use some cheap memmove()s + * to replace them by their standard identifiers. + * Let's illustrate this with an example: + * Assume the string: + * + * "IPC|MOUNT|PID" + * + * then we memmove() + * + * dest: del + 1 == OUNT|PID + * src: del + 3 == NT|PID + */ + if (!namespaces) + return -1; + + while ((del = strstr(namespaces, "MOUNT"))) + memmove(del + 1, del + 3, strlen(del) - 2); + + for (it = (char *[]){"NETWORK", "UTSNAME", NULL}; it && *it; it++) + while ((del = strstr(namespaces, *it))) + memmove(del + 3, del + 7, strlen(del) - 6); + + return 0; +} + int lxc_fill_namespace_flags(char *flaglist, int *flags) { char *token, *saveptr = NULL; diff --git a/src/lxc/namespace.h b/src/lxc/namespace.h index 4bfe9c4f5..1341af0e6 100644 --- a/src/lxc/namespace.h +++ b/src/lxc/namespace.h @@ -181,6 +181,7 @@ extern pid_t lxc_raw_clone_cb(int (*fn)(void *), void *args, extern int lxc_namespace_2_cloneflag(const char *namespace); extern int lxc_namespace_2_ns_idx(const char *namespace); +extern int lxc_namespace_2_std_identifiers(char *namespaces); extern int lxc_fill_namespace_flags(char *flaglist, int *flags); /** diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c index 6729a1e1e..d33d9c440 100644 --- a/src/lxc/tools/lxc_attach.c +++ b/src/lxc/tools/lxc_attach.c @@ -100,8 +100,6 @@ static int add_to_simple_array(char ***array, ssize_t *capacity, char *value) static int my_parser(struct lxc_arguments *args, int c, char *arg) { - char **it; - char *del; int ret; switch (c) { @@ -121,32 +119,13 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) case 's': namespace_flags = 0; - /* The identifiers for namespaces used with lxc-attach as given - * on the manpage do not align with the standard identifiers. - * This affects network, mount, and uts namespaces. The standard - * identifiers are: "mnt", "uts", and "net" whereas lxc-attach - * uses "MOUNT", "UTSNAME", and "NETWORK". So let's use some - * cheap memmove()s to replace them by their standard - * identifiers. Let's illustrate this with an example: - * Assume the string: - * - * "IPC|MOUNT|PID" - * - * then we memmove() - * - * dest: del + 1 == OUNT|PID - * src: del + 3 == NT|PID - */ - while ((del = strstr(arg, "MOUNT"))) - memmove(del + 1, del + 3, strlen(del) - 2); - - for (it = (char *[]){"NETWORK", "UTSNAME", NULL}; it && *it; it++) - while ((del = strstr(arg, *it))) - memmove(del + 3, del + 7, strlen(del) - 6); + if (lxc_namespace_2_std_identifiers(arg) < 0) + return -1; ret = lxc_fill_namespace_flags(arg, &namespace_flags); if (ret) return -1; + /* -s implies -e */ lxc_fill_elevated_privileges(NULL, &elevated_privileges); break; diff --git a/src/lxc/tools/lxc_unshare.c b/src/lxc/tools/lxc_unshare.c index b9745ef0e..669186ec1 100644 --- a/src/lxc/tools/lxc_unshare.c +++ b/src/lxc/tools/lxc_unshare.c @@ -244,8 +244,7 @@ static int write_id_mapping(pid_t pid, const char *buf, size_t buf_size) int main(int argc, char *argv[]) { - char *del; - char **it, **args; + char **args; int opt; int ret; char *namespaces = NULL; @@ -308,31 +307,9 @@ int main(int argc, char *argv[]) if (ret) exit(EXIT_FAILURE); - /* The identifiers for namespaces used with lxc-unshare as given on the - * manpage do not align with the standard identifiers. This affects - * network, mount, and uts namespaces. The standard identifiers are: - * "mnt", "uts", and "net" whereas lxc-unshare uses "MOUNT", "UTSNAME", - * and "NETWORK". So let's use some cheap memmove()s to replace them by - * their standard identifiers. Let's illustrate this with an example: - * Assume the string: - * - * "IPC|MOUNT|PID" - * - * then we memmove() - * - * dest: del + 1 == OUNT|PID - * src: del + 3 == NT|PID - */ - if (!namespaces) + if (lxc_namespace_2_std_identifiers(namespaces) < 0) usage(argv[0]); - while ((del = strstr(namespaces, "MOUNT"))) - memmove(del + 1, del + 3, strlen(del) - 2); - - for (it = (char *[]){"NETWORK", "UTSNAME", NULL}; it && *it; it++) - while ((del = strstr(namespaces, *it))) - memmove(del + 3, del + 7, strlen(del) - 6); - ret = lxc_fill_namespace_flags(namespaces, &flags); if (ret) usage(argv[0]);