]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
string_utils: switch to path_simplify() 3756/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Tue, 30 Mar 2021 15:20:51 +0000 (17:20 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Tue, 30 Mar 2021 15:20:51 +0000 (17:20 +0200)
Link: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=32689
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/confile_utils.c
src/lxc/criu.c
src/lxc/storage/overlay.c
src/lxc/string_utils.c
src/lxc/string_utils.h
src/tests/lxc-test-utils.c

index 4d52d044d129136e863aa44b104d37bffd3c9838..df25c031aad534621fedfeb7e03e4846faa954c0 100644 (file)
@@ -667,13 +667,13 @@ int set_config_string_item_max(char **conf_item, const char *value, size_t max)
 
 int set_config_path_item(char **conf_item, const char *value)
 {
-       __do_free char *normalized = NULL;
+       __do_free char *valdup = NULL;
 
-       normalized = lxc_deslashify(value);
-       if (!normalized)
-               return syserror_set(-ENOMEM, "Failed to normalize path config item");
+       valdup = path_simplify(value);
+       if (!valdup)
+               return -ENOMEM;
 
-       return set_config_string_item_max(conf_item, normalized, PATH_MAX);
+       return set_config_string_item_max(conf_item, valdup, PATH_MAX);
 }
 
 int set_config_bool_item(bool *conf_item, const char *value, bool empty_conf_action)
index c630bf74182fb640ecb06f55a13a5f04fb9de098..c7e49b1639580391e57ba68eb043e5436bf2ff6d 100644 (file)
@@ -319,7 +319,7 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
                                return log_error_errno(-ENOMEM, ENOMEM, "Failed to duplicate limit cgroup path");
                }
 
-               tmp = lxc_deslashify(cgroup_base_path);
+               tmp = path_simplify(cgroup_base_path);
                if (!tmp)
                        return log_error_errno(-ENOMEM, ENOMEM, "Failed to remove extraneous slashes from \"%s\"", tmp);
                free_move_ptr(cgroup_base_path, tmp);
index 770785cfdcc4a4af748fadc4cac84006fc28f246..5ff410e1142df11c013d7e3fa321da6e0b13f74a 100644 (file)
@@ -192,11 +192,11 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
                 * don't need to record a dependency. If we would restore would
                 * also fail.
                 */
-               clean_old_path = lxc_deslashify(oldpath);
+               clean_old_path = path_simplify(oldpath);
                if (!clean_old_path)
                        return log_error_errno(-ENOMEM, ENOMEM, "Failed to create clean path for \"%s\"", oldpath);
 
-               clean_new_path = lxc_deslashify(lxcpath);
+               clean_new_path = path_simplify(lxcpath);
                if (!clean_new_path)
                        return log_error_errno(-ENOMEM, ENOMEM, "Failed to create clean path for \"%s\"", lxcpath);
 
index 3312e62449b8e2bf725858c908289608e5d3eec1..18c64c11ef0642547a41480337baad7edde2600d 100644 (file)
@@ -195,7 +195,6 @@ char *lxc_string_join(const char *sep, const char **parts, bool use_as_prefix)
 char **lxc_normalize_path(const char *path)
 {
        char **components;
-       char **p;
        size_t components_len = 0;
        size_t pos = 0;
 
@@ -203,9 +202,6 @@ char **lxc_normalize_path(const char *path)
        if (!components)
                return NULL;
 
-       for (p = components; *p; p++)
-               components_len++;
-
        /* resolve '.' and '..' */
        for (pos = 0; pos < components_len;) {
                if (strequal(components[pos], ".") ||
@@ -231,47 +227,58 @@ char **lxc_normalize_path(const char *path)
        return components;
 }
 
-char *lxc_deslashify(const char *path)
+/* taken from systemd */
+char *path_simplify(const char *path)
 {
-       char *dup, *p;
-       char **parts = NULL;
-       size_t n, len;
+       __do_free char *path_new = NULL;
+       char *f, *t;
+       bool slash = false, ignore_slash = false, absolute;
 
-       dup = strdup(path);
-       if (!dup)
+       path_new = strdup(path);
+       if (!path_new)
                return NULL;
 
-       parts = lxc_normalize_path(dup);
-       if (!parts) {
-               free(dup);
-               return NULL;
+       if (is_empty_string(path_new))
+               return move_ptr(path_new);
+
+       absolute = abspath(path_new);
+
+       f = path_new;
+       if (*f == '.' && IN_SET(f[1], 0, '/')) {
+               ignore_slash = true;
+               f++;
        }
 
-       /* We'll end up here if path == "///" or path == "". */
-       if (!*parts) {
-               len = strlen(dup);
-               if (!len) {
-                       lxc_free_array((void **)parts, free);
-                       return dup;
-               }
+       for (t = path_new; *f; f++) {
 
-               n = strcspn(dup, "/");
-               if (n == len) {
-                       free(dup);
-                       lxc_free_array((void **)parts, free);
+               if (*f == '/') {
+                       slash = true;
+                       continue;
+               }
 
-                       p = strdup("/");
-                       if (!p)
-                               return NULL;
+               if (slash) {
+                       if (*f == '.' && IN_SET(f[1], 0, '/'))
+                               continue;
 
-                       return p;
+                       slash = false;
+                       if (ignore_slash)
+                               ignore_slash = false;
+                       else
+                               *(t++) = '/';
                }
+
+               *(t++) = *f;
+       }
+
+       if (t == path_new) {
+               if (absolute)
+                       *(t++) = '/';
+               else
+                       *(t++) = '.';
        }
 
-       p = lxc_string_join("/", (const char **)parts, *dup == '/');
-       free(dup);
-       lxc_free_array((void **)parts, free);
-       return p;
+       *t = 0;
+       return move_ptr(path_new);
 }
 
 char *lxc_append_paths(const char *first, const char *second)
index 76c765d3c774ee00fac6af29ec7759af0b86ba61..1bea9a01cdaed3e6dbcc53f91e7dd11331b48c1e 100644 (file)
@@ -196,4 +196,6 @@ static inline const char *fdstr(int fd)
             (__iterator = __it);                                               \
             __iterator = __it = strtok_r(NULL, __separators, &__p))
 
+__hidden extern char *path_simplify(const char *path);
+
 #endif /* __LXC_STRING_UTILS_H */
index 9b3e8cd1917f0b7a672abd05503e1f669ec7eb2b..3a26aecf306334ecd1930cddb1760d7b9b21b225 100644 (file)
 #include "macro.h"
 #include "utils.h"
 
-void test_lxc_deslashify(void)
+void test_path_simplify(void)
 {
        char *s = "/A///B//C/D/E/";
        char *t;
 
-       t = lxc_deslashify(s);
+       t = path_simplify(s);
        if (!t)
                exit(EXIT_FAILURE);
 
@@ -57,7 +57,7 @@ void test_lxc_deslashify(void)
 
        s = "/A";
 
-       t = lxc_deslashify(s);
+       t = path_simplify(s);
        if (!t)
                exit(EXIT_FAILURE);
 
@@ -65,7 +65,7 @@ void test_lxc_deslashify(void)
        free(t);
 
        s = "";
-       t = lxc_deslashify(s);
+       t = path_simplify(s);
        if (!t)
                exit(EXIT_FAILURE);
 
@@ -74,7 +74,7 @@ void test_lxc_deslashify(void)
 
        s = "//";
 
-       t = lxc_deslashify(s);
+       t = path_simplify(s);
        if (!t)
                exit(EXIT_FAILURE);
 
@@ -598,7 +598,7 @@ int main(int argc, char *argv[])
 {
        test_lxc_string_replace();
        test_lxc_string_in_array();
-       test_lxc_deslashify();
+       test_path_simplify();
        test_detect_ramfs_rootfs();
        test_lxc_safe_uint();
        test_lxc_safe_int();