diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 155279b..aa490f4 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -19,8 +19,8 @@ jobs: - arch: ppc64le distro: ubuntu_latest steps: - - uses: actions/checkout@v2.1.0 - - uses: uraimo/run-on-arch-action@v2.8.1 + - uses: actions/checkout@v4 + - uses: uraimo/run-on-arch-action@v3.0.1 name: Build id: build with: @@ -42,7 +42,7 @@ jobs: make -j $(nproc) - name: Archive build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4.6.2 with: name: fuse-overlayfs-${{ matrix.arch }}-${{ matrix.distro }} path: | @@ -61,7 +61,7 @@ jobs: TAGS: exclude_graphdriver_devicemapper exclude_graphdriver_btrfs no_libsubid steps: - name: checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: install dependencies run: | @@ -88,7 +88,7 @@ jobs: sudo cp fuse-overlayfs /sbin - name: Archive build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4.6.2 with: name: fuse-overlayfs-x86_64-ubuntu-latest path: | @@ -97,6 +97,9 @@ jobs: - name: run test run: | + sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 + sudo sysctl -w kernel.apparmor_restrict_unprivileged_unconfined=0 + case "${{ matrix.test }}" in ovl-whiteouts) sudo sh -c "(cd /unionmount-testsuite; unshare -m ./run --ov --fuse=fuse-overlayfs --xdev)" diff --git a/main.c b/main.c index f0f24a6..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,18 +5807,7 @@ main (int argc, char *argv[]) if (lo.mountpoint == NULL) error (EXIT_FAILURE, 0, "no mountpoint specified"); - if (lo.upperdir != NULL) - { - cleanup_free char *full_path = NULL; - - full_path = realpath (lo.upperdir, NULL); - if (full_path == NULL) - error (EXIT_FAILURE, errno, "cannot retrieve path for %s", lo.upperdir); - - lo.upperdir = strdup (full_path); - if (lo.upperdir == NULL) - error (EXIT_FAILURE, errno, "cannot allocate memory"); - } + unescape (lo.workdir); set_limits (); check_can_mknod (&lo); @@ -5890,7 +5931,7 @@ main (int argc, char *argv[]) if (! found) { /* If the mode is missing, set a standard value. */ - ret = write_permission_xattr (&lo, get_upper_layer (&lo)->fd, lo.upperdir, 0, 0, 0555); + ret = write_permission_xattr (&lo, get_upper_layer (&lo)->fd, get_upper_layer (&lo)->path, 0, 0, 0555); if (ret < 0) error (EXIT_FAILURE, errno, "write xattr `%s` to upperdir", name); } 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