Merge pull request #441 from giuseppe/unescape-dirs

main: Allow escaped colons in directory paths
This commit is contained in:
Giuseppe Scrivano 2025-04-29 22:28:08 +02:00 committed by GitHub
commit 3af99f6552
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 67 additions and 23 deletions

View File

@ -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)"

69
main.c
View File

@ -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);
}

View File

@ -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