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 2021-10-05 22:33:31
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/fuse-overlayfs (Old)
 and      /work/SRC/openSUSE:Factory/.fuse-overlayfs.new.2443 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "fuse-overlayfs"

Tue Oct  5 22:33:31 2021 rev:16 rq:922140 version:1.7.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/fuse-overlayfs/fuse-overlayfs.changes    
2021-03-02 15:15:02.653502844 +0100
+++ /work/SRC/openSUSE:Factory/.fuse-overlayfs.new.2443/fuse-overlayfs.changes  
2021-10-05 22:33:47.046862203 +0200
@@ -1,0 +2,26 @@
+Tue Sep 28 12:30:08 UTC 2021 - Klaus K??mpf <kkae...@suse.com>
+
+- Update to version 1.7.1
+  * set FUSE_CAP_POSIX_ACL only when it is supported by FUSE.
+  * treat statx failure with EINVAL as ENOSYS, so that the fallback
+    is attempted.
+
+- Update to version 1.7.0
+  * fix read xattrs for device files
+  * don't create whiteout files in opaque dirs.
+  * fix reading files when running with euid != 0.
+  * enable POSIX ACLs.
+
+- Update to version 1.6.0
+  * fix an invalid access when filtering internal xattrs that could
+    deal to a segfault.
+
+- Update to version 1.5.0
+  * honor FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT also for renames
+  * use strncpy instead of strcpy
+  * fix renameat2(RENAME_NOREPLACE) on older kernels that lack
+    device whiteouts for unprivileged users.
+  * fix creating a symlink on top of a removed file.
+  * fix copyup of xattrs longer than 256 bytes.
+
+-------------------------------------------------------------------

Old:
----
  v1.4.0.tar.gz

New:
----
  v1.7.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ fuse-overlayfs.spec ++++++
--- /var/tmp/diff_new_pack.mHrtpf/_old  2021-10-05 22:33:47.666863282 +0200
+++ /var/tmp/diff_new_pack.mHrtpf/_new  2021-10-05 22:33:47.666863282 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           fuse-overlayfs
-Version:        1.4.0
+Version:        1.7.1
 Release:        0
 Summary:        FUSE implementation for overlayfs
 License:        GPL-3.0-only

++++++ v1.4.0.tar.gz -> v1.7.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.4.0/.github/workflows/test.yaml 
new/fuse-overlayfs-1.7.1/.github/workflows/test.yaml
--- old/fuse-overlayfs-1.4.0/.github/workflows/test.yaml        2021-01-20 
09:29:06.000000000 +0100
+++ new/fuse-overlayfs-1.7.1/.github/workflows/test.yaml        2021-08-10 
08:59:01.000000000 +0200
@@ -51,7 +51,7 @@
           - test: ovl-whiteouts
     env:
       GOPATH: /root/go
-
+      TAGS: exclude_graphdriver_devicemapper exclude_graphdriver_btrfs 
no_libsubid
     steps:
     - name: checkout
       uses: actions/checkout@v2
@@ -62,9 +62,9 @@
             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 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)"
-            sudo go get github.com/containers/storage
-            sudo GOPATH=$GOPATH sh -c "(cd 
/root/go/src/github.com/containers/storage; sed -i -e 's|^AUTOTAGS.*$|AUTOTAGS 
:= exclude_graphdriver_devicemapper exclude_graphdriver_btrfs|' Makefile; make 
GO111MODULE=on containers-storage)"
 
     - name: run autogen.sh
       run: |
@@ -89,6 +89,7 @@
                 sudo tests/unlink.sh
                 sudo tests/alpine.sh
                 sudo sh -c "(cd 
/root/go/src/github.com/containers/storage/tests; JOBS=1 
STORAGE_OPTION=overlay.mount_program=/sbin/fuse-overlayfs 
STORAGE_DRIVER=overlay unshare -m ./test_runner.bash)"
+                tests/unpriv.sh
             ;;
             no-ovl-whiteouts)
                 sudo sh -c "(cd /unionmount-testsuite; 
FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT=1 unshare -m ./run --ov 
--fuse=fuse-overlayfs --xdev)"
@@ -96,5 +97,6 @@
                 sudo FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT=1 tests/unlink.sh
                 sudo FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT=1 tests/alpine.sh
                 sudo sh -c "(cd 
/root/go/src/github.com/containers/storage/tests; JOBS=1 
FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT=1 
STORAGE_OPTION=overlay.mount_program=/sbin/fuse-overlayfs 
STORAGE_DRIVER=overlay unshare -m ./test_runner.bash)"
+                FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT=1 tests/unpriv.sh
             ;;
         esac
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.4.0/NEWS 
new/fuse-overlayfs-1.7.1/NEWS
--- old/fuse-overlayfs-1.4.0/NEWS       2021-01-20 09:29:06.000000000 +0100
+++ new/fuse-overlayfs-1.7.1/NEWS       2021-08-10 08:59:01.000000000 +0200
@@ -1,3 +1,30 @@
+* fuse-overlayfs-1.7.1
+
+- set FUSE_CAP_POSIX_ACL only when it is supported by FUSE.
+- treat statx failure with EINVAL as ENOSYS, so that the fallback
+  is attempted.
+
+* fuse-overlayfs-1.7
+
+- fix read xattrs for device files
+- don't create whiteout files in opaque dirs.
+- fix reading files when running with euid != 0.
+- enable POSIX ACLs.
+
+* fuse-overlayfs-1.6
+
+- fix an invalid access when filtering internal xattrs that could
+  deal to a segfault.
+
+* fuse-overlayfs-1.5
+
+- honor FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT also for renames
+- use strncpy instead of strcpy
+- fix renameat2(RENAME_NOREPLACE) on older kernels that lack
+  device whiteouts for unprivileged users.
+- fix creating a symlink on top of a removed file.
+- fix copyup of xattrs longer than 256 bytes.
+
 * fuse-overlayfs-1.4
 
 - add squash_to_uid and squash_to_gid
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.4.0/configure.ac 
new/fuse-overlayfs-1.7.1/configure.ac
--- old/fuse-overlayfs-1.4.0/configure.ac       2021-01-20 09:29:06.000000000 
+0100
+++ new/fuse-overlayfs-1.7.1/configure.ac       2021-08-10 08:59:01.000000000 
+0200
@@ -1,5 +1,5 @@
 AC_PREREQ([2.69])
-AC_INIT([fuse-overlayfs], [1.4], [giuse...@scrivano.org])
+AC_INIT([fuse-overlayfs], [1.7.1], [giuse...@scrivano.org])
 AC_CONFIG_SRCDIR([main.c])
 AC_CONFIG_HEADERS([config.h])
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.4.0/direct.c 
new/fuse-overlayfs-1.7.1/direct.c
--- old/fuse-overlayfs-1.4.0/direct.c   2021-01-20 09:29:06.000000000 +0100
+++ new/fuse-overlayfs-1.7.1/direct.c   2021-08-10 08:59:01.000000000 +0200
@@ -43,17 +43,9 @@
 static int
 direct_listxattr (struct ovl_layer *l, const char *path, char *buf, size_t 
size)
 {
-  cleanup_close int fd = -1;
   char full_path[PATH_MAX];
-  int ret;
-
-  full_path[0] = '\0';
-  ret = open_fd_or_get_path (l, path, full_path, &fd, O_RDONLY);
-  if (ret < 0)
-    return ret;
 
-  if (fd >= 0)
-    return flistxattr (fd, buf, size);
+  strconcat3 (full_path, PATH_MAX, l->path, "/", path);
 
   return llistxattr (full_path, buf, size);
 }
@@ -61,17 +53,9 @@
 static int
 direct_getxattr (struct ovl_layer *l, const char *path, const char *name, char 
*buf, size_t size)
 {
-  cleanup_close int fd = -1;
   char full_path[PATH_MAX];
-  int ret;
 
-  full_path[0] = '\0';
-  ret = open_fd_or_get_path (l, path, full_path, &fd, O_RDONLY);
-  if (ret < 0)
-    return ret;
-
-  if (fd >= 0)
-    return fgetxattr (fd, name, buf, size);
+  strconcat3 (full_path, PATH_MAX, l->path, "/", path);
 
   return lgetxattr (full_path, name, buf, size);
 }
@@ -84,8 +68,7 @@
   struct statx stx;
 
   ret = statx (fd, "", AT_STATX_DONT_SYNC|AT_EMPTY_PATH, mask, &stx);
-
-  if (ret < 0 && errno == ENOSYS)
+  if (ret < 0 && (errno == ENOSYS || errno == EINVAL))
     goto fallback;
   if (ret == 0)
     {
@@ -112,8 +95,7 @@
   struct statx stx;
 
   ret = statx (l->fd, path, AT_STATX_DONT_SYNC|flags, mask, &stx);
-
-  if (ret < 0 && errno == ENOSYS)
+  if (ret < 0 && (errno == ENOSYS || errno == EINVAL))
     goto fallback;
   if (ret == 0)
     {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.4.0/fuse-overlayfs.1 
new/fuse-overlayfs-1.7.1/fuse-overlayfs.1
--- old/fuse-overlayfs-1.4.0/fuse-overlayfs.1   2021-01-20 09:29:06.000000000 
+0100
+++ new/fuse-overlayfs-1.7.1/fuse-overlayfs.1   2021-08-10 08:59:01.000000000 
+0200
@@ -43,11 +43,6 @@
 system as the upper dir.
 
 .PP
-\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
@@ -116,6 +111,16 @@
 .PP
 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.
+
+.PP
+This can be useful for higher latency file systems such as NFS, where
+counting the number of hard links for a directory with many files can
+be a slow operation. With this option enabled, the number of hard
+links reported when running stat for any directory is 1.
+
 
 .SH SEE ALSO
 .PP
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.4.0/fuse-overlayfs.1.md 
new/fuse-overlayfs-1.7.1/fuse-overlayfs.1.md
--- old/fuse-overlayfs-1.4.0/fuse-overlayfs.1.md        2021-01-20 
09:29:06.000000000 +0100
+++ new/fuse-overlayfs-1.7.1/fuse-overlayfs.1.md        2021-08-10 
08:59:01.000000000 +0200
@@ -35,10 +35,6 @@
 A directory used internally by fuse-overlays, must be on the same file
 system as the upper dir.
 
-**-o workdir=workdir**
-A directory used internally by fuse-overlays, must be on the same file
-system as the upper dir.
-
 **-o uidmapping=UID:MAPPED-UID:LEN[,UID2:MAPPED-UID2:LEN2]**
 **-o gidmapping=GID:MAPPED-GID:LEN[,GID2:MAPPED-GID2:LEN2]**
 Specifies the dynamic UID/GID mapping used by fuse-overlayfs when
@@ -93,6 +89,14 @@
 
 It has higher precedence over **squash_to_root**.
 
+**-o static_nlink**
+Set st_nlink to the static value 1 for all directories.
+
+This can be useful for higher latency file systems such as NFS, where
+counting the number of hard links for a directory with many files can
+be a slow operation. With this option enabled, the number of hard
+links reported when running stat for any directory is 1.
+
 # SEE ALSO
 
 **fuse**(8), **mount**(8), **user_namespaces**(7)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.4.0/fuse-overlayfs.h 
new/fuse-overlayfs-1.7.1/fuse-overlayfs.h
--- old/fuse-overlayfs-1.4.0/fuse-overlayfs.h   2021-01-20 09:29:06.000000000 
+0100
+++ new/fuse-overlayfs-1.7.1/fuse-overlayfs.h   2021-08-10 08:59:01.000000000 
+0200
@@ -99,11 +99,15 @@
   int squash_to_root;
   int squash_to_uid;
   int squash_to_gid;
+  int static_nlink;
 
   /* current uid/gid*/
   uid_t uid;
   uid_t gid;
 
+  /* process euid. */
+  uid_t euid;
+
   struct ovl_plugin_context *plugins_ctx;
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.4.0/main.c 
new/fuse-overlayfs-1.7.1/main.c
--- old/fuse-overlayfs-1.4.0/main.c     2021-01-20 09:29:06.000000000 +0100
+++ new/fuse-overlayfs-1.7.1/main.c     2021-08-10 08:59:01.000000000 +0200
@@ -158,8 +158,6 @@
 };
 #endif
 
-static bool disable_ovl_whiteout;
-
 static uid_t overflow_uid;
 static gid_t overflow_gid;
 
@@ -179,7 +177,7 @@
   char fmt[128];
   int l = snprintf (fmt, sizeof (fmt) - 1, "# INODES: %zu\n# NODES: %zu\n", 
stats.inodes, stats.nodes);
   fmt[l] = '\0';
-  write (STDERR_FILENO, fmt, l + 1);
+  (void) write (STDERR_FILENO, fmt, l + 1);
 }
 
 static double
@@ -225,6 +223,8 @@
    offsetof (struct ovl_data, squash_to_uid), 1},
   {"squash_to_gid=%d",
    offsetof (struct ovl_data, squash_to_gid), 1},
+  {"static_nlink",
+   offsetof (struct ovl_data, static_nlink), 1},
   {"volatile",  /* native overlay supports "volatile" to mean fsync=0.  */
    offsetof (struct ovl_data, fsync), 0},
   FUSE_OPT_END
@@ -290,6 +290,12 @@
   int ret;
   char path[PATH_MAX];
 
+  if (getenv ("FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT"))
+    {
+      can_mknod = false;
+      return;
+    }
+
   sprintf (path, "%lu", get_next_wd_counter ());
 
   ret = mknodat (lo->workdir_fd, path, S_IFCHR|0700, makedev (0, 0));
@@ -421,6 +427,9 @@
   if ((conn->capable & FUSE_CAP_WRITEBACK_CACHE) == 0)
     lo->writeback = 0;
 
+  if (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;
   if (lo->writeback)
     conn->want |= FUSE_CAP_WRITEBACK_CACHE;
@@ -723,7 +732,7 @@
         return 0;
     }
 
-  if (!disable_ovl_whiteout && !skip_mknod && can_mknod)
+  if (!skip_mknod && can_mknod)
     {
       char whiteout_path[PATH_MAX];
 
@@ -733,6 +742,21 @@
       if (ret == 0)
         return 0;
 
+      if (errno == EEXIST)
+        {
+          int saved_errno = errno;
+          struct stat st;
+
+          /* Check whether it is already a whiteout.  */
+          if (TEMP_FAILURE_RETRY (fstatat (get_upper_layer (lo)->fd, 
whiteout_path, &st, AT_SYMLINK_NOFOLLOW)) == 0
+              && (st.st_mode & S_IFMT) == S_IFCHR
+              && major (st.st_rdev) == 0
+              && minor (st.st_rdev) == 0)
+            return 0;
+
+          errno = saved_errno;
+        }
+
       if (errno != EPERM && errno != ENOTSUP)
         return -1;
 
@@ -742,7 +766,6 @@
 
   strconcat3 (whiteout_wh_path, PATH_MAX, parent->path, "/.wh.", name);
 
-
   fd = get_upper_layer (lo)->ds->openat (get_upper_layer (lo), 
whiteout_wh_path, O_CREAT|O_WRONLY|O_NONBLOCK, 0700);
   if (fd < 0 && errno != EEXIST)
     return -1;
@@ -881,15 +904,20 @@
   st->st_dev = node->tmp_dev;
   if (ret == 0 && node_dirp (node))
     {
-      struct ovl_node *it;
+      if (!data->static_nlink)
+        {
+          struct ovl_node *it;
 
-      st->st_nlink = 2;
+          st->st_nlink = 2;
 
-      for (it = hash_get_first (node->children); it; it = hash_get_next 
(node->children, it))
-        {
-          if (node_dirp (it))
-            st->st_nlink++;
+          for (it = hash_get_first (node->children); it; it = hash_get_next 
(node->children, it))
+            {
+              if (node_dirp (it))
+                st->st_nlink++;
+            }
         }
+      else
+        st->st_nlink = 1;
     }
 
   return ret;
@@ -919,7 +947,7 @@
 
   if (n->parent)
     {
-      if (hash_lookup (n->parent->children, n) == n)
+      if (n->parent->children && hash_lookup (n->parent->children, n) == n)
         hash_delete (n->parent->children, n);
       n->parent->loaded = 0;
       n->parent = NULL;
@@ -1040,6 +1068,10 @@
             needs_whiteout = true;
         }
 
+      // 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);
+
       if (needs_whiteout)
         {
           /* If the atomic rename+mknod failed, then fallback into doing it in 
two steps.  */
@@ -1348,9 +1380,10 @@
       char *tmp;
 
       s = fgetxattr (sfd, name, buffer, current_size);
-      if (s < 0)
+      if (s >= 0 && s < current_size)
         break;
-      if (s < current_size)
+
+      if (s < 0 && errno != ERANGE)
         break;
 
       current_size *= 2;
@@ -1384,7 +1417,7 @@
 
   ret = calloc (1, sizeof (*ret));
   if (ret == NULL)
-      return NULL;
+    return NULL;
 
   ret->parent = parent;
   ret->layer = layer;
@@ -1548,7 +1581,6 @@
 insert_node (struct ovl_node *parent, struct ovl_node *item, bool replace)
 {
   struct ovl_node *old = NULL, *prev_parent = item->parent;
-  int is_dir = node_dirp (item);
   int ret;
 
   if (prev_parent)
@@ -2088,7 +2120,7 @@
       return;
     }
 
-  if (node_dirp (node))
+  if (!lo->static_nlink && node_dirp (node))
     {
       node = reload_dir (lo, node);
       if (node == NULL)
@@ -2127,13 +2159,47 @@
   return (struct ovl_dirp *) (uintptr_t) fi->fh;
 }
 
+static int
+reload_tbl (struct ovl_data *lo, struct ovl_dirp *d, struct ovl_node *node)
+{
+  size_t counter = 0;
+  struct ovl_node *it;
+
+  node = reload_dir (lo, node);
+  if (node == NULL)
+    return -1;
+
+  if (d->tbl)
+    free (d->tbl);
+
+  d->offset = 0;
+  d->parent = node;
+  d->tbl_size = hash_get_n_entries (node->children) + 2;
+  d->tbl = calloc (sizeof (struct ovl_node *), d->tbl_size);
+  if (d->tbl == NULL)
+    {
+      errno = ENOMEM;
+      return -1;
+    }
+
+  d->tbl[counter++] = node;
+  d->tbl[counter++] = node->parent;
+
+  for (it = hash_get_first (node->children); it; it = hash_get_next 
(node->children, it))
+    {
+      it->ino->lookups++;
+      it->node_lookups++;
+      d->tbl[counter++] = it;
+    }
+
+  return 0;
+}
+
 static void
 ovl_opendir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
 {
-  size_t counter = 0;
   struct ovl_node *node;
   struct ovl_data *lo = ovl_data (req);
-  struct ovl_node *it;
   struct ovl_dirp *d = calloc (1, sizeof (struct ovl_dirp));
   cleanup_lock int l = enter_big_lock ();
 
@@ -2159,29 +2225,7 @@
       goto out_errno;
     }
 
-  node = reload_dir (lo, node);
-  if (node == NULL)
-    goto out_errno;
-
-  d->offset = 0;
   d->parent = node;
-  d->tbl_size = hash_get_n_entries (node->children) + 2;
-  d->tbl = malloc (sizeof (struct ovl_node *) * d->tbl_size);
-  if (d->tbl == NULL)
-    {
-      errno = ENOMEM;
-      goto out_errno;
-    }
-
-  d->tbl[counter++] = node;
-  d->tbl[counter++] = node->parent;
-
-  for (it = hash_get_first (node->children); it; it = hash_get_next 
(node->children, it))
-    {
-      it->ino->lookups++;
-      it->node_lookups++;
-      d->tbl[counter++] = it;
-    }
 
   fi->fh = (uintptr_t) d;
   if (get_timeout (lo) > 0)
@@ -2301,6 +2345,16 @@
       fuse_reply_err (req, errno);
       return;
     }
+
+  if (offset == 0 || d->tbl == NULL)
+    {
+      if (reload_tbl (lo, d, d->parent) < 0)
+        {
+          fuse_reply_err (req, errno);
+          return;
+        }
+    }
+
   p = buffer;
   for (; remaining > 0 && offset < d->tbl_size; offset++)
       {
@@ -2338,7 +2392,7 @@
           }
         else
           {
-            if (node_dirp (node))
+            if (!lo->static_nlink && node_dirp (node))
               {
                 node = reload_dir (lo, node);
                 if (node == NULL)
@@ -2347,7 +2401,6 @@
                     return;
                   }
               }
-
             memset (&e, 0, sizeof (e));
             ret = rpl_stat (req, node, -1, NULL, NULL, st);
             if (ret < 0)
@@ -2428,6 +2481,41 @@
   fuse_reply_err (req, 0);
 }
 
+/* in-place filter xattrs that cannot be accessed.  */
+static ssize_t
+filter_xattrs_list (char *buf, ssize_t len)
+{
+  ssize_t ret = 0;
+  char *it;
+
+  if (buf == NULL)
+    return len;
+
+  it = buf;
+
+  while (it < buf + len)
+    {
+      size_t it_len;
+
+      it_len = strlen (it) + 1;
+
+      if (can_access_xattr (it))
+        {
+          it += it_len;
+          ret += it_len;
+        }
+      else
+        {
+          char *next = it + it_len;
+
+          memmove (it, next, buf + len - next);
+          len -= it_len;
+        }
+    }
+
+  return ret;
+}
+
 static void
 ovl_listxattr (fuse_req_t req, fuse_ino_t ino, size_t size)
 {
@@ -2436,7 +2524,6 @@
   struct ovl_node *node;
   struct ovl_data *lo = ovl_data (req);
   cleanup_free char *buf = NULL;
-  size_t i;
   int ret;
 
   if (UNLIKELY (ovl_debug (req)))
@@ -2479,22 +2566,7 @@
       return;
     }
 
-  len = ret;
-
-  for (i = 0; buf && i < len;)
-    {
-      size_t current_len;
-      const char *cur_attr = buf + i;
-
-      current_len = strlen (cur_attr) + 1;
-      if (can_access_xattr (cur_attr))
-        i += current_len;
-      else
-        {
-          memmove (buf + i, cur_attr + current_len, len - current_len);
-          len -= current_len;
-        }
-    }
+  len = filter_xattrs_list (buf, ret);
 
   if (size == 0)
     fuse_reply_xattr (req, len);
@@ -2907,6 +2979,8 @@
   mode = st.st_mode;
   if (lo->xattr_permissions)
     mode |= 0755;
+  if (lo->euid > 0)
+    mode |= 0200;
 
   if ((mode & S_IFMT) == S_IFDIR)
     {
@@ -3923,19 +3997,23 @@
   l = release_big_lock ();
 
   memset (times, 0, sizeof (times));
-  times[0].tv_sec = UTIME_OMIT;
-  times[1].tv_sec = UTIME_OMIT;
+  times[0].tv_nsec = UTIME_OMIT;
+  times[1].tv_nsec = UTIME_OMIT;
   if (to_set & FUSE_SET_ATTR_ATIME)
-    times[0] = attr->st_atim;
-  else if (to_set & FUSE_SET_ATTR_ATIME_NOW)
-    times[0].tv_sec = UTIME_NOW;
+    {
+      times[0] = attr->st_atim;
+      if (to_set & FUSE_SET_ATTR_ATIME_NOW)
+        times[0].tv_nsec = UTIME_NOW;
+    }
 
   if (to_set & FUSE_SET_ATTR_MTIME)
-    times[1] = attr->st_mtim;
-  else if (to_set & FUSE_SET_ATTR_MTIME_NOW)
-    times[1].tv_sec = UTIME_NOW;
+    {
+      times[1] = attr->st_mtim;
+      if (to_set & FUSE_SET_ATTR_MTIME_NOW)
+        times[1].tv_nsec = UTIME_NOW;
+    }
 
-  if (times[0].tv_sec != UTIME_OMIT || times[1].tv_sec != UTIME_OMIT)
+  if (times[0].tv_nsec != UTIME_OMIT || times[1].tv_nsec != UTIME_OMIT)
     {
       if (fd >= 0)
         ret = futimens (fd, times);
@@ -4375,9 +4453,8 @@
   struct ovl_node *pnode, *node, *destnode, *destpnode;
   struct ovl_data *lo = ovl_data (req);
   int ret;
-  int saved_errno;
-  int srcfd = -1;
-  int destfd = -1;
+  cleanup_close int srcfd = -1;
+  cleanup_close int destfd = -1;
   struct ovl_node key;
   bool destnode_is_whiteout = false;
 
@@ -4515,8 +4592,19 @@
 
   /* Try to create the whiteout atomically, if it fails do the
      rename+mknod separately.  */
-  ret = direct_renameat2 (srcfd, name, destfd,
-                          newname, flags|RENAME_WHITEOUT);
+  if (! can_mknod)
+    {
+      ret = -1;
+      errno = EPERM;
+    }
+  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,
@@ -4527,6 +4615,8 @@
       ret = create_whiteout (lo, pnode, name, false, true);
       if (ret < 0)
         goto error;
+
+      pnode->loaded = 0;
     }
 
   if (delete_whiteout (lo, destfd, NULL, newname) < 0)
@@ -4549,20 +4639,12 @@
   node->loaded = 0;
 
   ret = 0;
-  goto cleanup;
+  fuse_reply_err (req, 0);
+  return;
 
  error:
   ret = -1;
-
- cleanup:
-  saved_errno = errno;
-  if (srcfd >= 0)
-    close (srcfd);
-  if (destfd >= 0)
-    close (destfd);
-  errno = saved_errno;
-
-  fuse_reply_err (req, ret == 0 ? 0 : errno);
+  fuse_reply_err (req, errno);
 }
 
 static void
@@ -4978,7 +5060,6 @@
   struct ovl_node *node;
   struct ovl_data *lo = ovl_data (req);
   cleanup_lock int l = 0;
-  char path[PATH_MAX];
 
   if (!lo->fsync)
     {
@@ -5004,9 +5085,6 @@
       return;
     }
 
-  if (fd < 0)
-    strcpy (path, node->path);
-
   if (! do_fsync)
     {
       fuse_reply_err (req, 0);
@@ -5014,7 +5092,7 @@
     }
 
   if (do_fsync)
-    ret = direct_fsync (node->layer, fd, path, datasync);
+    ret = direct_fsync (node->layer, fd, node->path, datasync);
 
   fuse_reply_err (req, ret == 0 ? 0 : errno);
 }
@@ -5406,7 +5484,12 @@
       if (dent->d_type != DT_DIR)
         {
           char *new_plugins = NULL;
-          asprintf (&new_plugins, "%s/%s:%s", PKGLIBEXECDIR, dent->d_name, 
plugins);
+          if (asprintf (&new_plugins, "%s/%s:%s", PKGLIBEXECDIR, dent->d_name, 
plugins) < 0)
+            {
+              free (plugins);
+              closedir (dp);
+              return NULL;
+            }
           free (plugins);
           plugins = new_plugins;
         }
@@ -5434,7 +5517,9 @@
                         .fsync = 1,
                         .squash_to_uid = -1,
                         .squash_to_gid = -1,
+                        .static_nlink = 0,
                         .xattr_permissions = 0,
+                        .euid = geteuid (),
                         .timeout = 1000000000.0,
                         .timeout_str = NULL,
                         .writeback = 1,
@@ -5448,9 +5533,6 @@
   struct ovl_layer *tmp_layer = NULL;
   struct fuse_args args = FUSE_ARGS_INIT (argc, newargv);
 
-  if (getenv ("FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT"))
-    disable_ovl_whiteout = true;
-
   memset (&opts, 0, sizeof (opts));
   if (fuse_opt_parse (&args, &lo, ovl_opts, fuse_opt_proc) == -1)
     error (EXIT_FAILURE, 0, "error parsing options");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.4.0/tests/fedora-installs.sh 
new/fuse-overlayfs-1.7.1/tests/fedora-installs.sh
--- old/fuse-overlayfs-1.4.0/tests/fedora-installs.sh   2021-01-20 
09:29:06.000000000 +0100
+++ new/fuse-overlayfs-1.7.1/tests/fedora-installs.sh   2021-08-10 
08:59:01.000000000 +0200
@@ -70,6 +70,9 @@
 
 touch lower/file-lower-layer
 
+# set a "big" xattr
+setfattr -n user.big-xattr -v "$(seq 1000 | tr -d '\n')" lower/file-lower-layer
+
 # no upper layer
 fuse-overlayfs -o lowerdir=lower merged
 
@@ -201,8 +204,52 @@
 touch merged/$(printf %${merged_max_filename_len}s | tr ' ' A})
 
 # If a file is removed but referenced, we must still be able to access it.
-echo 12345 > merged/toremove
-sleep 30 < merged/toremove &
+echo 12345 | tee merged/toremove
+exec 3<> merged/toremove
+sleep 90 &
+exec 3>&-
 sleep_pid=$!
 rm merged/toremove
-grep 12345 /proc/$sleep_pid/fd/0
+grep 12345 /proc/$sleep_pid/fd/3
+
+touch merged/a merged/b
+chmod 6 merged/a
+mv merged/a merged/x
+mv merged/b merged/a
+
+# https://github.com/containers/fuse-overlayfs/issues/279
+umount -l merged
+
+rm -rf lower upper workdir merged
+mkdir lower upper workdir merged
+mkdir lower/test
+touch lower/test/a.txt
+
+fuse-overlayfs -o lowerdir=lower,upperdir=upper,workdir=workdir merged
+
+(cd merged/test; touch a.txt; mv a.txt a2.txt; touch a3.txt; ln -s a3.txt 
a.txt)
+
+if test -e upperdir/test/.wh.a.txt; then
+   echo "whiteout file still exists" >&2
+   exit 1
+fi
+
+# https://github.com/containers/fuse-overlayfs/issues/306
+umount -l merged
+
+rm -rf lower upper workdir merged
+mkdir lower upper workdir merged
+
+mkdir -p lower/a/b
+fuse-overlayfs -o lowerdir=lower,upperdir=upper,workdir=workdir merged
+
+rm -rf merged/a
+mkdir -p merged/a/b
+rm -rf merged/a/b
+test \! -e upper/a/b
+
+mknod merged/dev-foo c 10 175
+attr -l merged/dev-foo
+
+umount merged
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.4.0/tests/unpriv.sh 
new/fuse-overlayfs-1.7.1/tests/unpriv.sh
--- old/fuse-overlayfs-1.4.0/tests/unpriv.sh    1970-01-01 01:00:00.000000000 
+0100
+++ new/fuse-overlayfs-1.7.1/tests/unpriv.sh    2021-08-10 08:59:01.000000000 
+0200
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+set -ex
+
+test $(id -u) -gt 0
+
+rm -rf unpriv-test
+mkdir unpriv-test
+
+cd unpriv-test
+
+mkdir lower upper workdir merged
+
+touch lower/a lower/b
+chmod 444 lower/a lower/b
+
+fuse-overlayfs -o lowerdir=lower,upperdir=upper,workdir=workdir merged
+
+rm -f merged/a
+chmod 406 merged/b
+
+test \! -e merged/a
+test $(stat --printf=%a merged/b) -eq 406
+test $(stat --printf=%a upper/b) -eq 406
+if [ ${FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT:-0} -eq 1 ]; then
+    test -e upper/.wh.a
+else
+    test -c upper/a
+fi
+
+fusermount -u merged || [ $? -eq "${EXPECT_UMOUNT_STATUS:-0}" ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.4.0/utils.h 
new/fuse-overlayfs-1.7.1/utils.h
--- old/fuse-overlayfs-1.4.0/utils.h    2021-01-20 09:29:06.000000000 +0100
+++ new/fuse-overlayfs-1.7.1/utils.h    2021-08-10 08:59:01.000000000 +0200
@@ -18,7 +18,9 @@
 #ifndef UTILS_H
 # define UTILS_H
 
+#ifndef _GNU_SOURCE
 # define _GNU_SOURCE
+#endif
 
 # include <config.h>
 

Reply via email to