From 27cabd561b038f16d8c4a1356ab36d118b593cae Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 28 Apr 2025 14:32:58 +0200 Subject: [PATCH] main: Allow escaped colons in directory paths Allow directory paths specified for lowerdir, upperdir and workdir to contain colon characters. Previously, colons were unconditionally treated as separators, making it impossible to use directories with colons in their names. Closes: https://github.com/containers/fuse-overlayfs/issues/440 Signed-off-by: Giuseppe Scrivano --- main.c | 55 +++++++++++++++++++++++++++++++++++++++- tests/fedora-installs.sh | 8 +++--- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/main.c b/main.c index dc87457..9909e38 100644 --- a/main.c +++ b/main.c @@ -1924,6 +1924,58 @@ cleanup_layerp (struct ovl_layer **p) #define cleanup_layer __attribute__ ((cleanup (cleanup_layerp))) +static void +unescape (char *input) +{ + char *dest = input; + + if (input == NULL) + return; + + for (; *input; input++) + { + if (*input == '\\') + continue; + + *dest++ = *input; + } + *dest = '\0'; +} + +static char * +get_next_path (char *it, char **saveptr) +{ + char *ret; + + if (*saveptr == NULL) + *saveptr = it; + + ret = *saveptr; + + if (*ret == '\0') + return NULL; + + while (1) + { + if (**saveptr == '\0') + break; + + if (**saveptr == ':') + { + **saveptr = '\0'; + (*saveptr)++; + break; + } + else if (**saveptr == '\\') + { + memmove (*saveptr, *saveptr + 1, strlen (*saveptr) + 1); + } + + (*saveptr)++; + } + return ret; +} + static struct ovl_layer * read_dirs (struct ovl_data *lo, char *path, bool low, struct ovl_layer *layers) { @@ -1942,7 +1994,7 @@ read_dirs (struct ovl_data *lo, char *path, bool low, struct ovl_layer *layers) while (last && last->next) last = last->next; - for (it = strtok_r (buf, ":", &saveptr); it; it = strtok_r (NULL, ":", &saveptr)) + for (it = get_next_path (buf, &saveptr); it; it = get_next_path (NULL, &saveptr)) { char *name, *data; char *it_path = it; @@ -5755,6 +5807,7 @@ main (int argc, char *argv[]) if (lo.mountpoint == NULL) error (EXIT_FAILURE, 0, "no mountpoint specified"); + unescape (lo.workdir); set_limits (); check_can_mknod (&lo); diff --git a/tests/fedora-installs.sh b/tests/fedora-installs.sh index 6eaecfb..6b946ff 100755 --- a/tests/fedora-installs.sh +++ b/tests/fedora-installs.sh @@ -2,17 +2,17 @@ set -xeuo pipefail -mkdir lower upper workdir merged +mkdir lower:1 upper:2 workdir:3 merged -fuse-overlayfs -o sync=0,lowerdir=lower,upperdir=upper,workdir=workdir,suid,dev merged +fuse-overlayfs -o 'sync=0,lowerdir=lower\\:1,upperdir=upper\\:2,workdir=workdir\\:3,suid,dev' merged docker run --rm -v $(pwd)/merged:/merged fedora dnf --use-host-config --installroot /merged --releasever 41 install -y glibc-common gedit umount merged # Make sure workdir is empty, and move the upper layer down -rm -rf workdir lower -mv upper lower +rm -rf lower:1 workdir:3 +mv upper:2 lower mkdir upper workdir gcc -static -o suid-test $(dirname $0)/suid-test.c