Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package fuse-overlayfs for openSUSE:Factory checked in at 2022-12-07 17:33:10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/fuse-overlayfs (Old) and /work/SRC/openSUSE:Factory/.fuse-overlayfs.new.1835 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "fuse-overlayfs" Wed Dec 7 17:33:10 2022 rev:17 rq:1040074 version:1.10 Changes: -------- --- /work/SRC/openSUSE:Factory/fuse-overlayfs/fuse-overlayfs.changes 2021-10-05 22:33:47.046862203 +0200 +++ /work/SRC/openSUSE:Factory/.fuse-overlayfs.new.1835/fuse-overlayfs.changes 2022-12-07 17:33:17.051986932 +0100 @@ -1,0 +2,24 @@ +Sun Dec 4 21:47:14 UTC 2022 - Dirk Müller <dmuel...@suse.com> + +- update to 1.10: + * main: use /proc/self/fd to read xattrs. + * main: inherit ACLs for new files/dirs. + * main: fix passing noatime. + * main: add checks for valid /proc mount. + * main: fix copy_file_range for deleted files. + * main: fix creating links of just deleted files. + * main: fix setting attributes on file without permissions. + * main: ignore EOVERFLOW when copying xattrs. + * main: set the correct value for RENAME_NOREPLACE when it is not already + defined in the system headers. + * main: create source whiteout only when needed + * main: fix missing source whiteout when destination is whiteout + * main: fix lookup if underlying path is a symlink, but a directory on a + upper directory. + * main: fix race when looking up an inode that was renamed. + * main: fix type used for ioctl. + * main: honor user.overlay. xattrs. Native overlay uses user.overlay to + store the overlay metadata instead of trusted.overlay. + * main: add a mount flag to disable ACLs. + +------------------------------------------------------------------- Old: ---- v1.7.1.tar.gz New: ---- v1.10.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ fuse-overlayfs.spec ++++++ --- /var/tmp/diff_new_pack.9XyLmI/_old 2022-12-07 17:33:17.943991816 +0100 +++ /var/tmp/diff_new_pack.9XyLmI/_new 2022-12-07 17:33:17.947991838 +0100 @@ -1,7 +1,7 @@ # # spec file for package fuse-overlayfs # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: fuse-overlayfs -Version: 1.7.1 +Version: 1.10 Release: 0 Summary: FUSE implementation for overlayfs License: GPL-3.0-only ++++++ v1.7.1.tar.gz -> v1.10.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fuse-overlayfs-1.7.1/.github/workflows/release.yaml new/fuse-overlayfs-1.10/.github/workflows/release.yaml --- old/fuse-overlayfs-1.7.1/.github/workflows/release.yaml 2021-08-10 08:59:01.000000000 +0200 +++ new/fuse-overlayfs-1.10/.github/workflows/release.yaml 2022-11-30 16:33:29.000000000 +0100 @@ -10,18 +10,9 @@ runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: "Register QEMU to /proc/sys/fs/binfmt_misc" - run: docker run --rm --privileged linuxkit/binfmt:v0.8 - - name: "Fetch buildx binary" - run: | - wget -O buildx https://github.com/docker/buildx/releases/download/v0.4.1/buildx-v0.4.1.linux-amd64 - chmod +x buildx - - name: "Initialize buildx" - run: | - ./buildx create --name cross --platform=amd64,arm,arm64,s390x,ppc64le --use - ./buildx inspect --bootstrap + - uses: docker/setup-buildx-action@v1 - name: "Build binaries from Containerfile.cross" - run: ./buildx build -o /tmp --platform=amd64,arm64,arm,s390x,ppc64le -f Containerfile.cross . + run: docker buildx build -o /tmp --platform=amd64,arm64,arm,s390x,ppc64le,riscv64 -f Containerfile.cross . - name: "Create /tmp/artifact" run: | mkdir -p /tmp/artifact @@ -30,6 +21,7 @@ mv /tmp/linux_arm_v7/fuse-overlayfs /tmp/artifact/fuse-overlayfs-armv7l mv /tmp/linux_s390x/fuse-overlayfs /tmp/artifact/fuse-overlayfs-s390x mv /tmp/linux_ppc64le/fuse-overlayfs /tmp/artifact/fuse-overlayfs-ppc64le + mv /tmp/linux_riscv64/fuse-overlayfs /tmp/artifact/fuse-overlayfs-riscv64 - name: "SHA256SUMS" run: (cd /tmp/artifact; sha256sum *) | tee /tmp/SHA256SUMS - name: "Create release" @@ -86,6 +78,15 @@ asset_path: /tmp/artifact/fuse-overlayfs-ppc64le asset_name: fuse-overlayfs-ppc64le asset_content_type: application/octet-stream + - name: "Upload fuse-overlayfs-riscv64" + uses: actions/upload-release-asset@v1.0.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: /tmp/artifact/fuse-overlayfs-riscv64 + asset_name: fuse-overlayfs-riscv64 + asset_content_type: application/octet-stream - name: "Upload SHA256SUMS" uses: actions/upload-release-asset@v1.0.2 env: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fuse-overlayfs-1.7.1/.github/workflows/test.yaml new/fuse-overlayfs-1.10/.github/workflows/test.yaml --- old/fuse-overlayfs-1.7.1/.github/workflows/test.yaml 2021-08-10 08:59:01.000000000 +0200 +++ new/fuse-overlayfs-1.10/.github/workflows/test.yaml 2022-11-30 16:33:29.000000000 +0100 @@ -38,9 +38,16 @@ run: | ./autogen.sh - ./configure + LIBS="-ldl" LDFLAGS="-static" ./configure make -j $(nproc) + - name: Archive build artifacts + uses: actions/upload-artifact@v3 + with: + name: fuse-overlayfs-${{ matrix.arch }}-${{ matrix.distro }} + path: | + fuse-overlayfs + Test: runs-on: ubuntu-20.04 strategy: @@ -61,8 +68,8 @@ sudo apt-get update -q -y sudo apt-get install -q -y attr automake autotools-dev git make gcc pkg-config xz-utils python3.8 g++ python3-setuptools libdevmapper-dev btrfs-progs libbtrfs-dev go-md2man parallel wget libfuse3-dev bats - sudo mkdir -p /lower /upper /mnt - sudo GOPATH=$GOPATH go get -d github.com/containers/storage + sudo mkdir -p /lower /upper /mnt $GOPATH/src/github.com/containers + sudo sh -c "cd $GOPATH/src/github.com/containers; git clone --depth=1 https://github.com/containers/storage" sudo TAGS="$TAGS" GOPATH=$GOPATH sh -c "(cd $GOPATH/src/github.com/containers/storage; sed -i -e 's|^AUTOTAGS.*$|AUTOTAGS := $TAGS|' Makefile; make GO111MODULE=on containers-storage)" sudo sh -c "(cd /; git clone https://github.com/amir73il/unionmount-testsuite.git)" @@ -72,7 +79,7 @@ - name: run configure run: | - ./configure + LIBS="-ldl" LDFLAGS="-static" ./configure - name: build and install run: | @@ -80,6 +87,14 @@ sudo make -j install sudo cp fuse-overlayfs /sbin + - name: Archive build artifacts + uses: actions/upload-artifact@v3 + with: + name: fuse-overlayfs-x86_64-ubuntu20.04 + path: | + fuse-overlayfs + if: ${{ matrix.test == 'ovl-whiteouts' }} + - name: run test run: | case "${{ matrix.test }}" in diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fuse-overlayfs-1.7.1/.gitignore new/fuse-overlayfs-1.10/.gitignore --- old/fuse-overlayfs-1.7.1/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/fuse-overlayfs-1.10/.gitignore 2022-11-30 16:33:29.000000000 +0100 @@ -0,0 +1,20 @@ +*.a +*.cache +*.o +.deps +Makefile +Makefile.in +aclocal.m4 +build-aux +config.h +config.h.in +config.log +config.status +configure +fuse-overlayfs +lib/.deps +lib/Makefile +lib/Makefile.in +lib/limits.h +lib/sys/types.h +stamp-h1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fuse-overlayfs-1.7.1/Containerfile.cross new/fuse-overlayfs-1.10/Containerfile.cross --- old/fuse-overlayfs-1.7.1/Containerfile.cross 2021-08-10 08:59:01.000000000 +0200 +++ new/fuse-overlayfs-1.10/Containerfile.cross 2022-11-30 16:33:29.000000000 +0100 @@ -1,14 +1,16 @@ -FROM --platform=$BUILDPLATFORM debian:10 AS fuse-overlayfs +FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.1.0 AS xx +FROM --platform=$BUILDPLATFORM ubuntu:22.04 AS fuse-overlayfs RUN apt-get update && \ apt-get install --no-install-recommends -y \ - git ca-certificates libc6-dev gcc make automake autoconf pkgconf libfuse3-dev file curl go-md2man -RUN curl -o /cross.sh https://raw.githubusercontent.com/tonistiigi/binfmt/18c3d40ae2e3485e4de5b453e8460d6872b24d6b/binfmt/scripts/cross.sh && chmod +x /cross.sh + git make automake autoconf pkgconf file go-md2man COPY . /fuse-overlayfs WORKDIR /fuse-overlayfs +COPY --from=xx / / ARG TARGETPLATFORM -RUN /cross.sh install gcc pkgconf libfuse3-dev | sh +ENV DEBIAN_FRONTEND=noninteractive +RUN xx-apt-get install -y gcc libfuse3-dev RUN ./autogen.sh && \ - CC=$(/cross.sh cross-prefix)-gcc LD=$(/cross.sh cross-prefix)-ld LIBS="-ldl" LDFLAGS="-static" ./configure && \ + LIBS="-ldl" LDFLAGS="-static" ./configure --host=$(xx-info) && \ make && mkdir /out && cp fuse-overlayfs /out && \ file /out/fuse-overlayfs | grep "statically linked" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fuse-overlayfs-1.7.1/NEWS new/fuse-overlayfs-1.10/NEWS --- old/fuse-overlayfs-1.7.1/NEWS 2021-08-10 08:59:01.000000000 +0200 +++ new/fuse-overlayfs-1.10/NEWS 2022-11-30 16:33:29.000000000 +0100 @@ -1,3 +1,38 @@ +* fuse-overlayfs-1.10 + +- main: use /proc/self/fd to read xattrs. +- main: inherit ACLs for new files/dirs. +- main: fix passing noatime. +- main: add checks for valid /proc mount. +- main: fix copy_file_range for deleted files. +- main: fix creating links of just deleted files. + +* fuse-overlayfs-1.9 + +- main: fix setting attributes on file without permissions. +- main: ignore EOVERFLOW when copying xattrs. +- main: set the correct value for RENAME_NOREPLACE when it is not already + defined in the system headers. +- main: create source whiteout only when needed +- main: fix missing source whiteout when destination is whiteout + +* fuse-overlayfs-1.8.2 + +- main: fix lookup if underlying path is a symlink, but a directory on + a upper directory. + +* fuse-overlayfs-1.8.1 + +- main: fix race when looking up an inode that was renamed. +- main: fix type used for ioctl. + +* fuse-overlayfs-1.8 + +- main: honor user.overlay. xattrs. Native overlay uses user.overlay + to store the overlay metadata instead of trusted.overlay, let's + honor it as well. +- main: add a mount flag to disable ACLs. + * fuse-overlayfs-1.7.1 - set FUSE_CAP_POSIX_ACL only when it is supported by FUSE. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fuse-overlayfs-1.7.1/README.md new/fuse-overlayfs-1.10/README.md --- old/fuse-overlayfs-1.7.1/README.md 2021-08-10 08:59:01.000000000 +0200 +++ new/fuse-overlayfs-1.10/README.md 2022-11-30 16:33:29.000000000 +0100 @@ -19,7 +19,7 @@ Requirements: ======================================================= -If your are not using the static build as explained in the next chapter, your system needs `libfuse` > v3.2.1. +If you are not using the static build as explained in the next chapter, your system needs `libfuse` > v3.2.1. * On Fedora: `dnf install fuse3-devel` * On Ubuntu > v19.04: `apt install libfuse3-dev` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fuse-overlayfs-1.7.1/configure.ac new/fuse-overlayfs-1.10/configure.ac --- old/fuse-overlayfs-1.7.1/configure.ac 2021-08-10 08:59:01.000000000 +0200 +++ new/fuse-overlayfs-1.10/configure.ac 2022-11-30 16:33:29.000000000 +0100 @@ -1,5 +1,5 @@ AC_PREREQ([2.69]) -AC_INIT([fuse-overlayfs], [1.7.1], [giuse...@scrivano.org]) +AC_INIT([fuse-overlayfs], [1.10], [giuse...@scrivano.org]) AC_CONFIG_SRCDIR([main.c]) AC_CONFIG_HEADERS([config.h]) @@ -30,7 +30,7 @@ AC_DEFINE([USE_DIFF_HASH], 1, [Use the same hashing function as GNU diff]) -PKG_CHECK_MODULES([FUSE], [fuse3 >= 3.2.1], [AC_DEFINE([HAVE_FUSE], 1, [Define if libfuse is available])], [AC_MSG_ERROR([*** libfuse not found])]]) +PKG_CHECK_MODULES([FUSE], [fuse3 >= 3.2.1], [AC_DEFINE([HAVE_FUSE], 1, [Define if libfuse3 is available])], [AC_MSG_ERROR([*** libfuse3 not found])]]) old_CFLAGS=$CFLAGS old_LDFLAGS=$LDFLAGS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fuse-overlayfs-1.7.1/direct.c new/fuse-overlayfs-1.10/direct.c --- old/fuse-overlayfs-1.7.1/direct.c 2021-08-10 08:59:01.000000000 +0200 +++ new/fuse-overlayfs-1.10/direct.c 2022-11-30 16:33:29.000000000 +0100 @@ -44,8 +44,13 @@ direct_listxattr (struct ovl_layer *l, const char *path, char *buf, size_t size) { char full_path[PATH_MAX]; - - strconcat3 (full_path, PATH_MAX, l->path, "/", path); + int ret; + ret = snprintf (full_path, sizeof (full_path), "/proc/self/fd/%d/%s", l->fd, path); + if (ret >= sizeof (full_path)) + { + errno = ENAMETOOLONG; + return -1; + } return llistxattr (full_path, buf, size); } @@ -54,9 +59,13 @@ direct_getxattr (struct ovl_layer *l, const char *path, const char *name, char *buf, size_t size) { char full_path[PATH_MAX]; - - strconcat3 (full_path, PATH_MAX, l->path, "/", path); - + int ret; + ret = snprintf (full_path, sizeof (full_path), "/proc/self/fd/%d/%s", l->fd, path); + if (ret >= sizeof (full_path)) + { + errno = ENAMETOOLONG; + return -1; + } return lgetxattr (full_path, name, buf, size); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fuse-overlayfs-1.7.1/fuse-overlayfs.1 new/fuse-overlayfs-1.10/fuse-overlayfs.1 --- old/fuse-overlayfs-1.7.1/fuse-overlayfs.1 2021-08-10 08:59:01.000000000 +0200 +++ new/fuse-overlayfs-1.10/fuse-overlayfs.1 2022-11-30 16:33:29.000000000 +0100 @@ -1,55 +1,55 @@ .nh -.TH fuse\-overlayfs 1 "User Commands" +.TH fuse-overlayfs 1 "User Commands" .SH NAME .PP -fuse\-overlayfs \- overlayfs FUSE implementation +fuse-overlayfs - overlayfs FUSE implementation .SH SYNOPSIS .PP mounting - fuse\-overlayfs [\-f] [\-\-debug] [\-o OPTS] MOUNT\_TARGET + fuse-overlayfs [-f] [--debug] [-o OPTS] MOUNT_TARGET .PP unmounting - fusermount \-u mountpoint + fusermount -u mountpoint .SH DESCRIPTION .PP -fuse\-overlayfs provides an overlayfs FUSE implementation so that it +fuse-overlayfs provides an overlayfs FUSE implementation so that it can be used since Linux 4.18 by unprivileged users in an user namespace. .SH OPTIONS .PP -\fB\-\-debug\fP +\fB--debug\fP Enable debugging mode, can be very noisy. .PP -\fB\-o lowerdir=low1[:low2...]\fP +\fB-o lowerdir=low1[:low2...]\fP A list of directories separated by \fB\fC:\fR\&. Their content is merged. .PP -\fB\-o upperdir=upperdir\fP +\fB-o upperdir=upperdir\fP A directory merged on top of all the lowerdirs where all the changes done to the file system will be written. .PP -\fB\-o workdir=workdir\fP -A directory used internally by fuse\-overlays, must be on the same file +\fB-o workdir=workdir\fP +A directory used internally by fuse-overlays, must be on the same file system as the upper dir. .PP -\fB\-o uidmapping=UID:MAPPED\-UID:LEN[,UID2:MAPPED\-UID2:LEN2]\fP -\fB\-o gidmapping=GID:MAPPED\-GID:LEN[,GID2:MAPPED\-GID2:LEN2]\fP -Specifies the dynamic UID/GID mapping used by fuse\-overlayfs when +\fB-o uidmapping=UID:MAPPED-UID:LEN[,UID2:MAPPED-UID2:LEN2]\fP +\fB-o gidmapping=GID:MAPPED-GID:LEN[,GID2:MAPPED-GID2:LEN2]\fP +Specifies the dynamic UID/GID mapping used by fuse-overlayfs when reading/writing files to the system. .PP -The fuse\-overlayfs dynamic mapping is an alternative and cheaper way +The fuse-overlayfs dynamic mapping is an alternative and cheaper way to chown'ing the files on the host to accommodate the user namespace settings. @@ -62,13 +62,13 @@ For example, given on the host two files like: .PP -$ stat \-c %u:%g lower/a lower/b +$ stat -c %u:%g lower/a lower/b 0:0 1:1 .PP When we run in a user namespace with the following configuration: -$ cat /proc/self/uid\_map +$ cat /proc/self/uid_map 0 1000 1 1 110000 65536 @@ -76,7 +76,7 @@ We would see: .PP -$ stat \-c %u:%g merged/a merged/b +$ stat -c %u:%g merged/a merged/b 65534:65534 65534:65534 @@ -86,13 +86,13 @@ mapped. .PP -In the above example, if we mount the fuse\-overlayfs file system using: -\fB\fC\-ouidmapping=0:1000:1:1:110000:65536,gidmapping=0:1000:1:1:110000:65536\fR, +In the above example, if we mount the fuse-overlayfs file system using: +\fB\fC-ouidmapping=0:1000:1:1:110000:65536,gidmapping=0:1000:1:1:110000:65536\fR, which is the namespace configuration specified on a single line, we'd see from the same user namespace: .PP -$ stat \-c %u:%g merged/a merged/b +$ stat -c %u:%g merged/a merged/b 0:0 1:1 @@ -100,20 +100,20 @@ Those are the same IDs visible from outside the user namespace. .PP -\fB\-o squash\_to\_root\fP +\fB-o squash_to_root\fP Every file and directory is owned by the root user (0:0). .PP -\fB\-o squash\_to\_uid=uid\fP -\fB\-o squash\_to\_gid=gid\fP +\fB-o squash_to_uid=uid\fP +\fB-o squash_to_gid=gid\fP Every file and directory is owned by the specified uid or gid. .PP -It has higher precedence over \fBsquash\_to\_root\fP\&. +It has higher precedence over \fBsquash_to_root\fP\&. .PP -\fB\-o static\_nlink\fP -Set st\_nlink to the static value 1 for all directories. +\fB-o static_nlink\fP +Set st_nlink to the static value 1 for all directories. .PP This can be useful for higher latency file systems such as NFS, where @@ -121,13 +121,17 @@ be a slow operation. With this option enabled, the number of hard links reported when running stat for any directory is 1. +.PP +\fB-o noacl\fP +Disable ACL support in the FUSE file system. + .SH SEE ALSO .PP -\fBfuse\fP(8), \fBmount\fP(8), \fBuser\_namespaces\fP(7) +\fBfuse\fP(8), \fBmount\fP(8), \fBuser_namespaces\fP(7) .SH AVAILABILITY .PP -The fuse\-overlayfs command is available from -\fBhttps://github.com/containers/fuse\-overlayfs\fP under GNU GENERAL PUBLIC LICENSE Version 3 or later. +The fuse-overlayfs command is available from +\fBhttps://github.com/containers/fuse-overlayfs\fP under GNU GENERAL PUBLIC LICENSE Version 3 or later. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fuse-overlayfs-1.7.1/fuse-overlayfs.1.md new/fuse-overlayfs-1.10/fuse-overlayfs.1.md --- old/fuse-overlayfs-1.7.1/fuse-overlayfs.1.md 2021-08-10 08:59:01.000000000 +0200 +++ new/fuse-overlayfs-1.10/fuse-overlayfs.1.md 2022-11-30 16:33:29.000000000 +0100 @@ -97,6 +97,9 @@ be a slow operation. With this option enabled, the number of hard links reported when running stat for any directory is 1. +**-o noacl** +Disable ACL support in the FUSE file system. + # SEE ALSO **fuse**(8), **mount**(8), **user_namespaces**(7) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fuse-overlayfs-1.7.1/fuse-overlayfs.h new/fuse-overlayfs-1.10/fuse-overlayfs.h --- old/fuse-overlayfs-1.7.1/fuse-overlayfs.h 2021-08-10 08:59:01.000000000 +0200 +++ new/fuse-overlayfs-1.10/fuse-overlayfs.h 2022-11-30 16:33:29.000000000 +0100 @@ -92,6 +92,7 @@ double timeout; int threaded; int fsync; + int noacl; int fast_ino_check; int writeback; int disable_xattrs; @@ -101,6 +102,8 @@ int squash_to_gid; int static_nlink; + int volatile_mode; + /* current uid/gid*/ uid_t uid; uid_t gid; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fuse-overlayfs-1.7.1/main.c new/fuse-overlayfs-1.10/main.c --- old/fuse-overlayfs-1.7.1/main.c 2021-08-10 08:59:01.000000000 +0200 +++ new/fuse-overlayfs-1.10/main.c 2022-11-30 16:33:29.000000000 +0100 @@ -37,7 +37,9 @@ #include <dirent.h> #include <assert.h> #include <errno.h> +#include <linux/magic.h> #include <err.h> +#include <sys/vfs.h> #include <sys/ioctl.h> #ifdef HAVE_SYS_SENDFILE_H # include <sys/sendfile.h> @@ -64,6 +66,8 @@ #include <utils.h> #include <plugin.h> +#define ACL_XATTR "system.posix_acl_default" + #ifndef TEMP_FAILURE_RETRY #define TEMP_FAILURE_RETRY(expression) \ (__extension__ \ @@ -124,9 +128,12 @@ } #endif +#ifndef RENAME_NOREPLACE +# define RENAME_NOREPLACE (1 << 0) +#endif + #ifndef RENAME_EXCHANGE # define RENAME_EXCHANGE (1 << 1) -# define RENAME_NOREPLACE (1 << 2) #endif #ifndef RENAME_WHITEOUT @@ -137,6 +144,8 @@ #define ORIGIN_XATTR "user.fuseoverlayfs.origin" #define OPAQUE_XATTR "user.fuseoverlayfs.opaque" #define XATTR_CONTAINERS_PREFIX "user.containers." +#define UNPRIVILEGED_XATTR_PREFIX "user.overlay." +#define UNPRIVILEGED_OPAQUE_XATTR "user.overlay.opaque" #define PRIVILEGED_XATTR_PREFIX "trusted.overlay." #define PRIVILEGED_OPAQUE_XATTR "trusted.overlay.opaque" #define PRIVILEGED_ORIGIN_XATTR "trusted.overlay.origin" @@ -226,7 +235,9 @@ {"static_nlink", offsetof (struct ovl_data, static_nlink), 1}, {"volatile", /* native overlay supports "volatile" to mean fsync=0. */ - offsetof (struct ovl_data, fsync), 0}, + offsetof (struct ovl_data, volatile_mode), 1}, + {"noacl", + offsetof (struct ovl_data, noacl), 1}, FUSE_OPT_END }; @@ -285,6 +296,34 @@ } static void +check_writeable_proc () +{ + struct statvfs svfs; + struct statfs sfs; + + int ret; + + ret = statfs ("/proc", &sfs); + if (ret < 0) + { + fprintf (stderr, "error stating /proc: %m\n"); + return; + } + + if (sfs.f_type != PROC_SUPER_MAGIC) + { + fprintf (stderr, "invalid file system type found on /proc: %m\n"); + return; + } + + if (svfs.f_flag & ST_RDONLY) + { + fprintf (stderr, "/proc seems to be mounted as readonly, it can lead to unexpected failures"); + return; + } +} + +static void check_can_mknod (struct ovl_data *lo) { int ret; @@ -427,7 +466,7 @@ if ((conn->capable & FUSE_CAP_WRITEBACK_CACHE) == 0) lo->writeback = 0; - if (conn->capable & FUSE_CAP_POSIX_ACL) + if ((lo->noacl == 0) && (conn->capable & FUSE_CAP_POSIX_ACL)) conn->want |= FUSE_CAP_POSIX_ACL; conn->want |= FUSE_CAP_DONT_MASK | FUSE_CAP_SPLICE_READ | FUSE_CAP_SPLICE_WRITE | FUSE_CAP_SPLICE_MOVE; @@ -493,8 +532,9 @@ static bool can_access_xattr (const char *name) { - return !has_prefix (name, XATTR_PREFIX) \ - && !has_prefix (name, PRIVILEGED_XATTR_PREFIX); + return !has_prefix (name, XATTR_PREFIX) + && !has_prefix (name, PRIVILEGED_XATTR_PREFIX) + && !has_prefix (name, UNPRIVILEGED_XATTR_PREFIX); } static ssize_t @@ -682,6 +722,8 @@ s = l->ds->getxattr (l, path, PRIVILEGED_OPAQUE_XATTR, b, sizeof (b)); if (s < 0 && errno == ENODATA) + s = l->ds->getxattr (l, path, UNPRIVILEGED_OPAQUE_XATTR, b, sizeof (b)); + if (s < 0 && errno == ENODATA) s = l->ds->getxattr (l, path, OPAQUE_XATTR, b, sizeof (b)); if (s < 0) @@ -902,7 +944,8 @@ st->st_ino = node->tmp_ino; st->st_dev = node->tmp_dev; - if (ret == 0 && node_dirp (node)) + + if (node_dirp (node)) { if (!data->static_nlink) { @@ -919,6 +962,14 @@ else st->st_nlink = 1; } + else + { + struct ovl_node *n; + + st->st_nlink = 0; + for (n = node->ino->node; n; n = n->next_link) + st->st_nlink++; + } return ret; } @@ -1070,7 +1121,7 @@ // if the parent directory is opaque, there's no need to put a whiteout in it. if (node->parent != NULL) - needs_whiteout = needs_whiteout && (is_directory_opaque(get_upper_layer(lo), node->parent->path) < 1); + needs_whiteout = needs_whiteout && (is_directory_opaque (get_upper_layer(lo), node->parent->path) < 1); if (needs_whiteout) { @@ -1188,7 +1239,7 @@ for (it = ino->node; it; it = it->next_link) { - if (n->parent == it->parent && node_compare (n, it)) + if (node_dirp (it) || strcmp (n->path, it->path) == 0) { node_free (n); return it; @@ -1478,6 +1529,9 @@ int r; r = it->ds->file_exists (it, whiteout_path); + if (r < 0 && errno == EACCES) + break; + if (r < 0 && errno != ENOENT && errno != ENOTDIR && errno != ENAMETOOLONG) return NULL; @@ -1652,8 +1706,9 @@ for (it = lo->layers; it && !stop_lookup; it = it->next) { - int ret; + struct stat st; DIR *dp = NULL; + int ret; if (n->last_layer == it) stop_lookup = true; @@ -1665,6 +1720,17 @@ if (ret == 0) break; + ret = it->ds->statat (it, path, &st, AT_SYMLINK_NOFOLLOW, STATX_TYPE); + if (ret < 0) + { + if (errno == ENOENT || errno == ENOTDIR || errno == ENAMETOOLONG) + continue; + return NULL; + } + /* not a directory, stop lookup in lower layers. */ + if ((st.st_mode & S_IFMT) != S_IFDIR) + break; + dp = it->ds->opendir (it, path); if (dp == NULL) continue; @@ -1713,6 +1779,8 @@ strconcat3 (node_path, PATH_MAX, n->path, "/", dent->d_name); ret = it->ds->file_exists (it, whiteout_path); + if (ret < 0 && errno == EACCES) + continue; if (ret < 0 && errno != ENOENT && errno != ENOTDIR && errno != ENAMETOOLONG) { it->ds->closedir (dp); @@ -1980,7 +2048,13 @@ pnode = inode_to_node (lo, parent); if (name == NULL) - return pnode; + { + /* Prefer a version that is loaded. */ + for (node = pnode; node; node = node->next_link) + if (node->parent) + return node; + return pnode; + } if (has_prefix (name, ".wh.")) { @@ -2013,7 +2087,7 @@ { int saved_errno = errno; - if (errno == ENOENT || errno == ENOTDIR) + if (errno == ENOENT || errno == ENOTDIR || errno == EACCES) { if (node) continue; @@ -2481,6 +2555,33 @@ fuse_reply_err (req, 0); } +static int +inherit_acl (struct ovl_data *lo, struct ovl_node *parent, int targetfd, const char *path) +{ + cleanup_free char *v = NULL; + cleanup_close int dfd = -1; + int s; + + if (parent == NULL || lo->noacl) + return 0; + + dfd = safe_openat (node_dirfd (parent), parent->path, O_DIRECTORY, 0); + if (dfd < 0) + return -1; + + s = safe_read_xattr (&v, dfd, ACL_XATTR, 4096); + if (s < 0) + { + if (errno == ENODATA || errno == ENOTSUP) + return 0; + return -1; + } + if (targetfd >= 0) + return fsetxattr (targetfd, ACL_XATTR, v, s, 0); + + return setxattr (path, ACL_XATTR, v, s, 0); +} + /* in-place filter xattrs that cannot be accessed. */ static ssize_t filter_xattrs_list (char *buf, ssize_t len) @@ -2675,7 +2776,11 @@ s = safe_read_xattr (&v, sfd, it, 256); if (s < 0) - return -1; + { + if (errno == EOVERFLOW) + continue; + return -1; + } if (fsetxattr (dfd, it, v, s, 0) < 0) { @@ -2838,6 +2943,10 @@ goto out; } + ret = inherit_acl (lo, parent, dfd, NULL); + if (ret < 0) + goto out; + ret = renameat (lo->workdir_fd, wd_tmp_file_name, dirfd, name); if (ret < 0) { @@ -3303,6 +3412,7 @@ node_set_name (&key, (char *) name); rm = hash_delete (pnode->children, &key); + fuse_lowlevel_notify_inval_inode (lo->se, node_to_inode (node), -1, 0); if (rm) { ret = hide_node (lo, rm, true); @@ -3610,6 +3720,10 @@ if (fd < 0) return fd; + ret = inherit_acl (lo, n, fd, NULL); + if (ret < 0) + return ret; + if (need_delete_whiteout && delete_whiteout (lo, -1, p, name) < 0) return -1; @@ -3960,10 +4074,7 @@ case S_IFREG: cleaned_up_fd = fd = TEMP_FAILURE_RETRY (safe_openat (dirfd, node->path, O_NOFOLLOW|O_NONBLOCK|(to_set & FUSE_SET_ATTR_SIZE ? O_WRONLY : 0), 0)); if (fd < 0) - { - fuse_reply_err (req, errno); - return; - } + strconcat3 (path, PATH_MAX, get_upper_layer (lo)->path, "/", node->path); break; case S_IFDIR: @@ -3971,10 +4082,7 @@ if (fd < 0) { if (errno != ELOOP) - { - fuse_reply_err (req, errno); - return; - } + strconcat3 (path, PATH_MAX, get_upper_layer (lo)->path, "/", node->path); } break; @@ -4458,6 +4566,13 @@ struct ovl_node key; bool destnode_is_whiteout = false; + pnode = do_lookup_file (lo, parent, NULL); + if (pnode == NULL || pnode->whiteout) + { + fuse_reply_err (req, ENOENT); + return; + } + node = do_lookup_file (lo, parent, name); if (node == NULL || node->whiteout) { @@ -4480,7 +4595,6 @@ return; } } - pnode = node->parent; destpnode = do_lookup_file (lo, newparent, NULL); destnode = NULL; @@ -4510,16 +4624,21 @@ if (node == NULL) goto error; + /* If NOREPLACE flag is given, check if we should throw an error now. + If not, just remove the flag as it might cause problems with replacing whiteouts later. */ if (flags & RENAME_NOREPLACE && destnode && !destnode->whiteout) { errno = EEXIST; goto error; } + else + flags = flags & ~RENAME_NOREPLACE; if (destnode) { size_t destnode_whiteouts = 0; + errno = EINVAL; if (!destnode->whiteout && destnode->tmp_ino == node->tmp_ino && destnode->tmp_dev == node->tmp_dev) goto error; @@ -4568,17 +4687,6 @@ } } - /* If the destnode is a whiteout, first attempt to EXCHANGE the source and the destination, - so that with one operation we get both the rename and the whiteout created. */ - if (destnode_is_whiteout) - { - ret = direct_renameat2 (srcfd, name, destfd, newname, flags|RENAME_EXCHANGE); - if (ret == 0) - goto done; - - /* If it fails for any reason, fallback to the more articulated method. */ - } - /* If the node is a directory we must ensure there is no whiteout at the destination, otherwise the renameat2 will fail. Create a .wh.$NAME style whiteout file until the renameat2 is completed. */ @@ -4590,39 +4698,51 @@ unlinkat (destfd, newname, 0); } - /* Try to create the whiteout atomically, if it fails do the - rename+mknod separately. */ - if (! can_mknod) + bool src_needs_whiteout = (node->last_layer != get_upper_layer (lo)); + + if (src_needs_whiteout) { - ret = -1; - errno = EPERM; + /* Trying to atomically both rename and create the whiteout. + If destination is a whiteout, we can EXCHANGE source and destination and reuse the old whiteout. + If not, we can try to atomically create one with the WHITEOUT flag. */ + if (destnode_is_whiteout) + ret = direct_renameat2 (srcfd, name, destfd, newname, flags|RENAME_EXCHANGE); + else + { + if (! can_mknod) + { + ret = -1; + errno = EPERM; + } + else + ret = direct_renameat2 (srcfd, name, destfd, newname, flags|RENAME_WHITEOUT); + } + + /* If atomic whiteout creation failed, fall back to separate rename and whiteout creation. */ + if (ret < 0) + { + ret = direct_renameat2 (srcfd, name, destfd, newname, flags); + if (ret < 0) + goto error; + + ret = create_whiteout (lo, pnode, name, false, true); + if (ret < 0) + goto error; + } } else { - ret = direct_renameat2 (srcfd, name, destfd, - newname, flags|RENAME_WHITEOUT); - } - /* If the destination is a whiteout, just overwrite it. */ - if (ret < 0 && errno == EEXIST) - ret = direct_renameat2 (srcfd, name, destfd, newname, flags & ~RENAME_NOREPLACE); - if (ret < 0) - { - ret = direct_renameat2 (srcfd, name, destfd, - newname, flags); - if (ret < 0) - goto error; - - ret = create_whiteout (lo, pnode, name, false, true); + ret = direct_renameat2 (srcfd, name, destfd, newname, flags); if (ret < 0) goto error; - - pnode->loaded = 0; } + pnode->loaded = 0; + + /* If the destination was .wh. style whiteout, it was not replaced automatically, so delete it. */ if (delete_whiteout (lo, destfd, NULL, newname) < 0) goto error; - done: hash_delete (pnode->children, node); free (node->name); @@ -4858,6 +4978,14 @@ return; } + ret = inherit_acl (lo, pnode, -1, path); + if (ret < 0) + { + fuse_reply_err (req, errno); + unlinkat (lo->workdir_fd, wd_tmp_file_name, 0); + return; + } + ret = renameat (lo->workdir_fd, wd_tmp_file_name, get_upper_layer (lo)->fd, path); if (ret < 0) { @@ -5117,12 +5245,6 @@ return do_fsync (req, ino, datasync, -1); } -static int -direct_ioctl (struct ovl_layer *l, int fd, int cmd, unsigned long *r) -{ - return ioctl (fd, cmd, &r); -} - static void ovl_ioctl (fuse_req_t req, fuse_ino_t ino, int cmd, void *arg, struct fuse_file_info *fi, unsigned int flags, @@ -5133,7 +5255,7 @@ cleanup_close int cleaned_fd = -1; struct ovl_node *node; int fd = -1; - unsigned long r; + int r = 0; if (flags & FUSE_IOCTL_COMPAT) { @@ -5189,7 +5311,7 @@ l = release_big_lock (); - if (direct_ioctl (node->layer, fd, cmd, &r) < 0) + if (ioctl (fd, cmd, &r, sizeof (r)) < 0) fuse_reply_err (req, errno); else fuse_reply_ioctl (req, 0, &r, out_bufsz ? sizeof (r) : 0); @@ -5288,7 +5410,10 @@ return; } - fd = node->layer->ds->openat (node->layer, node->path, O_NONBLOCK|O_NOFOLLOW|O_RDONLY, 0755); + if (node->hidden) + fd = openat (node->hidden_dirfd, node->path, O_NONBLOCK|O_NOFOLLOW|O_RDONLY, 0755); + else + fd = node->layer->ds->openat (node->layer, node->path, O_NONBLOCK|O_NOFOLLOW|O_RDONLY, 0755); if (fd < 0) { fuse_reply_err (req, errno); @@ -5423,7 +5548,10 @@ } /* Ignore unknown arguments. */ if (key == -1) - return 0; + { + fprintf (stderr, "unknown argument ignored: %s\n", arg); + return 0; + } return 1; } @@ -5442,7 +5570,7 @@ if (geteuid() == 0) newargv[1] = "-odefault_permissions,allow_other,suid,noatime,lazytime"; else - newargv[1] = "-odefault_permissions,noatime=1"; + newargv[1] = "-odefault_permissions,noatime"; for (i = 1; i < *argc; i++) newargv[i + 1] = argv[i]; (*argc)++; @@ -5515,6 +5643,7 @@ .redirect_dir = NULL, .mountpoint = NULL, .fsync = 1, + .noacl = 0, .squash_to_uid = -1, .squash_to_gid = -1, .static_nlink = 0, @@ -5523,6 +5652,7 @@ .timeout = 1000000000.0, .timeout_str = NULL, .writeback = 1, + .volatile_mode = 0, }; struct fuse_loop_config fuse_conf = { .clone_fd = 1, @@ -5585,6 +5715,10 @@ set_limits (); check_can_mknod (&lo); + check_writeable_proc (); + + if (lo.volatile_mode) + lo.fsync = 0; if (lo.debug) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fuse-overlayfs-1.7.1/tests/fedora-installs.sh new/fuse-overlayfs-1.10/tests/fedora-installs.sh --- old/fuse-overlayfs-1.7.1/tests/fedora-installs.sh 2021-08-10 08:59:01.000000000 +0200 +++ new/fuse-overlayfs-1.10/tests/fedora-installs.sh 2022-11-30 16:33:29.000000000 +0100 @@ -48,14 +48,14 @@ fuse-overlayfs -o sync=0,lowerdir=lower,upperdir=upper,workdir=workdir,suid,dev merged # https://github.com/containers/fuse-overlayfs/issues/86 -docker run --rm -v $(pwd)/merged:/merged centos:8 yum --installroot /merged -y --releasever 8 install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm +docker run --rm -v $(pwd)/merged:/merged quay.io/centos/centos:stream8 yum --installroot /merged -y --releasever 8 install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm umount merged # fast_ino_check fuse-overlayfs -o fast_ino_check=1,sync=0,lowerdir=lower,upperdir=upper,workdir=workdir,suid,dev merged -docker run --rm -v $(pwd)/merged:/merged centos:8 yum --installroot /merged -y --releasever 8 install nano +docker run --rm -v $(pwd)/merged:/merged quay.io/centos/centos:stream8 yum --installroot /merged -y --releasever 8 install nano mkdir merged/a-directory @@ -251,5 +251,17 @@ mknod merged/dev-foo c 10 175 attr -l merged/dev-foo -umount merged +# https://github.com/containers/fuse-overlayfs/issues/337 +umount -l merged + +rm -rf lower upper workdir merged +mkdir lower upper workdir merged +mkdir upper/foo +ln -s not/existing lower/foo + +fuse-overlayfs -o lowerdir=lower,upperdir=upper,workdir=workdir merged + +stat merged/foo + +umount merged diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fuse-overlayfs-1.7.1/utils.h new/fuse-overlayfs-1.10/utils.h --- old/fuse-overlayfs-1.7.1/utils.h 2021-08-10 08:59:01.000000000 +0200 +++ new/fuse-overlayfs-1.10/utils.h 2022-11-30 16:33:29.000000000 +0100 @@ -23,14 +23,13 @@ #endif # include <config.h> - -# include <unistd.h> -# include <stdio.h> -# include <sys/types.h> # include <dirent.h> +# include <fcntl.h> +# include <limits.h> +# include <stdio.h> # include <stdlib.h> # include <sys/types.h> -# include <fcntl.h> +# include <unistd.h> # include "fuse-overlayfs.h" # define XATTR_OVERRIDE_STAT "user.fuseoverlayfs.override_stat"