Hello community,

here is the log from the commit of package fuse-overlayfs for openSUSE:Factory 
checked in at 2020-07-15 11:30:01
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/fuse-overlayfs (Old)
 and      /work/SRC/openSUSE:Factory/.fuse-overlayfs.new.3060 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "fuse-overlayfs"

Wed Jul 15 11:30:01 2020 rev:12 rq:819290 version:1.1.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/fuse-overlayfs/fuse-overlayfs.changes    
2020-04-25 20:08:53.471617868 +0200
+++ /work/SRC/openSUSE:Factory/.fuse-overlayfs.new.3060/fuse-overlayfs.changes  
2020-07-15 11:32:27.782046890 +0200
@@ -1,0 +2,12 @@
+Wed Jun 24 13:10:52 UTC 2020 - Ralf Haferkamp <rha...@suse.com>
+
+- Update to v1.1.0
+  - use openat2(2) when available.
+  - accept "ro" as mount option.
+  - fix set mtime for a symlink.
+  - fix some issues reported by static analysis.
+  - fix potential infinite loop on a short read.
+  - fix creating a directory if the destination already exists
+    in the upper layer.
+
+-------------------------------------------------------------------

Old:
----
  fuse-overlayfs-1.0.0.tar.xz

New:
----
  fuse-overlayfs-1.1.0.tar.xz

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

Other differences:
------------------
++++++ fuse-overlayfs.spec ++++++
--- /var/tmp/diff_new_pack.NUNBiv/_old  2020-07-15 11:32:28.938048106 +0200
+++ /var/tmp/diff_new_pack.NUNBiv/_new  2020-07-15 11:32:28.942048110 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           fuse-overlayfs
-Version:        1.0.0
+Version:        1.1.0
 Release:        0
 Summary:        FUSE implementation for overlayfs
 License:        GPL-3.0-only

++++++ _service ++++++
--- /var/tmp/diff_new_pack.NUNBiv/_old  2020-07-15 11:32:28.970048139 +0200
+++ /var/tmp/diff_new_pack.NUNBiv/_new  2020-07-15 11:32:28.970048139 +0200
@@ -3,8 +3,8 @@
     <param name="url">https://github.com/containers/fuse-overlayfs.git</param>
     <param name="scm">git</param>
     <param name="filename">fuse-overlayfs</param>
-    <param name="versionformat">1.0.0</param>
-    <param name="revision">v1.0.0</param>
+    <param name="versionformat">1.1.0</param>
+    <param name="revision">v1.1.0</param>
   </service>
   <service name="set_version" mode="disabled">
     <param name="basename">fuse-overlayfs</param>

++++++ fuse-overlayfs-1.0.0.tar.xz -> fuse-overlayfs-1.1.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.0.0/.travis.yml 
new/fuse-overlayfs-1.1.0/.travis.yml
--- old/fuse-overlayfs-1.0.0/.travis.yml        2020-04-17 11:10:44.000000000 
+0200
+++ new/fuse-overlayfs-1.1.0/.travis.yml        2020-06-18 09:15:04.000000000 
+0200
@@ -34,7 +34,7 @@
   - (git clone --depth 1 -b 0.51.1 https://github.com/mesonbuild/meson.git; cd 
meson; sudo python3.5 ./setup.py install)
   - (git clone --depth 1 https://github.com/bats-core/bats-core; cd bats-core; 
sudo ./install.sh /usr/local)
   - ($GO get github.com/containers/storage; cd 
$GOPATH/src/github.com/containers/storage; sed -i -e 's|^AUTOTAGS.*$|AUTOTAGS 
:= exclude_graphdriver_devicemapper exclude_graphdriver_btrfs|' Makefile; make 
GO=$GO GO111MODULE=on containers-storage)
-  - (wget 
https://github.com/libfuse/libfuse/releases/download/fuse-3.6.2/fuse-3.6.2.tar.xz;
 tar xf fuse-3.6.2.tar.xz; cd fuse-3.6.2; mkdir build; cd build; meson .. 
--prefix /usr && ninja && sudo ninja install)
+  - (wget 
https://github.com/libfuse/libfuse/releases/download/fuse-3.9.1/fuse-3.9.1.tar.xz;
 tar xf fuse-3.9.1.tar.xz; cd fuse-3.9.1; mkdir build; cd build; meson .. 
--prefix /usr && ninja && sudo ninja install)
 script:
   - ./autogen.sh || travis_terminate 1;
   - ./configure || travis_terminate 1;
@@ -44,6 +44,6 @@
   - (cd /unionmount-testsuite; sudo FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT=1 
unshare -m ./run --ov --fuse=fuse-overlayfs --xdev) || travis_terminate 1;
   - sudo tests/fedora-installs.sh || travis_terminate 1;
   - sudo tests/unlink.sh || travis_terminate 1;
-  - (cd $GOPATH/src/github.com/containers/storage/tests; sudo 
STORAGE_OPTION=overlay.mount_program=/sbin/fuse-overlayfs 
STORAGE_DRIVER=overlay unshare -m ./test_runner.bash) || travis_terminate 1;
-  - (cd $GOPATH/src/github.com/containers/storage/tests; sudo 
FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT=1 
STORAGE_OPTION=overlay.mount_program=/sbin/fuse-overlayfs 
STORAGE_DRIVER=overlay unshare -m ./test_runner.bash) || travis_terminate 1;
+  - (cd $GOPATH/src/github.com/containers/storage/tests; sudo JOBS=1 
STORAGE_OPTION=overlay.mount_program=/sbin/fuse-overlayfs 
STORAGE_DRIVER=overlay unshare -m ./test_runner.bash) || travis_terminate 1;
+  - (cd $GOPATH/src/github.com/containers/storage/tests; sudo JOBS=1 
FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT=1 
STORAGE_OPTION=overlay.mount_program=/sbin/fuse-overlayfs 
STORAGE_DRIVER=overlay unshare -m ./test_runner.bash) || travis_terminate 1;
   - docker run --rm  -v $(pwd):/fuse-overlayfs alpine-build sh -c 'cd 
/fuse-overlayfs; ./autogen.sh && ./configure && make clean && make'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.0.0/NEWS 
new/fuse-overlayfs-1.1.0/NEWS
--- old/fuse-overlayfs-1.0.0/NEWS       2020-04-17 11:10:44.000000000 +0200
+++ new/fuse-overlayfs-1.1.0/NEWS       2020-06-18 09:15:04.000000000 +0200
@@ -1,3 +1,12 @@
+* fuse-overlayfs-1.1.0
+
+- use openat2(2) when available.
+- accept "ro" as mount option.
+- fix set mtime for a symlink.
+- fix some issues reported by static analysis.
+- fix potential infinite loop on a short read.
+- fix creating a directory if the destination already exists in the upper 
layer.
+
 * fuse-overlayfs-1.0.0
 
 - fix portability issue to 32 bits archs.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.0.0/SECURITY.md 
new/fuse-overlayfs-1.1.0/SECURITY.md
--- old/fuse-overlayfs-1.0.0/SECURITY.md        1970-01-01 01:00:00.000000000 
+0100
+++ new/fuse-overlayfs-1.1.0/SECURITY.md        2020-06-18 09:15:04.000000000 
+0200
@@ -0,0 +1,3 @@
+## Security and Disclosure Information Policy for the fuse-overlayfs Project
+
+The fuse-overlayfs Project follows the [Security and Disclosure Information 
Policy](https://github.com/containers/common/blob/master/SECURITY.md) for the 
Containers Projects.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.0.0/configure.ac 
new/fuse-overlayfs-1.1.0/configure.ac
--- old/fuse-overlayfs-1.0.0/configure.ac       2020-04-17 11:10:44.000000000 
+0200
+++ new/fuse-overlayfs-1.1.0/configure.ac       2020-06-18 09:15:04.000000000 
+0200
@@ -1,5 +1,5 @@
 AC_PREREQ([2.69])
-AC_INIT([fuse-overlayfs], [1.0.0], [giuse...@scrivano.org])
+AC_INIT([fuse-overlayfs], [1.1.0], [giuse...@scrivano.org])
 AC_CONFIG_SRCDIR([main.c])
 AC_CONFIG_HEADERS([config.h])
 
@@ -75,8 +75,7 @@
 AC_SEARCH_LIBS([dlopen], [dl], [], [AC_MSG_ERROR([unable to find dlopen()])])
 
 AC_FUNC_ERROR_AT_LINE
-AC_FUNC_MALLOC
-AC_CHECK_FUNCS([open_by_handle_at error memset strdup copy_file_range statx])
+AC_CHECK_FUNCS([malloc open_by_handle_at error memset strdup copy_file_range 
statx])
 
 AC_CONFIG_FILES([Makefile lib/Makefile])
 AC_OUTPUT
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.0.0/direct.c 
new/fuse-overlayfs-1.1.0/direct.c
--- old/fuse-overlayfs-1.0.0/direct.c   2020-04-17 11:10:44.000000000 +0200
+++ new/fuse-overlayfs-1.1.0/direct.c   2020-06-18 09:15:04.000000000 +0200
@@ -129,7 +129,7 @@
   cleanup_close int cleanup_fd = -1;
   DIR *dp = NULL;
 
-  cleanup_fd = TEMP_FAILURE_RETRY (openat (l->fd, path, O_DIRECTORY));
+  cleanup_fd = TEMP_FAILURE_RETRY (safe_openat (l->fd, path, O_DIRECTORY, 0));
   if (cleanup_fd < 0)
     return NULL;
 
@@ -151,7 +151,7 @@
 static int
 direct_openat (struct ovl_layer *l, const char *path, int flags, mode_t mode)
 {
-  return TEMP_FAILURE_RETRY (openat (l->fd, path, flags, mode));
+  return TEMP_FAILURE_RETRY (safe_openat (l->fd, path, flags, mode));
 }
 
 static ssize_t
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.0.0/main.c 
new/fuse-overlayfs-1.1.0/main.c
--- old/fuse-overlayfs-1.0.0/main.c     2020-04-17 11:10:44.000000000 +0200
+++ new/fuse-overlayfs-1.1.0/main.c     2020-06-18 09:15:04.000000000 +0200
@@ -494,7 +494,7 @@
           return -1;
     }
  create_opq_whiteout:
-  opq_whiteout_fd = TEMP_FAILURE_RETRY (openat (fd, OPAQUE_WHITEOUT, 
O_CREAT|O_WRONLY|O_NONBLOCK, 0700));
+  opq_whiteout_fd = TEMP_FAILURE_RETRY (safe_openat (fd, OPAQUE_WHITEOUT, 
O_CREAT|O_WRONLY|O_NONBLOCK, 0700));
   return (opq_whiteout_fd >= 0 || ret == 0) ? 0 : -1;
 }
 
@@ -823,7 +823,7 @@
 }
 
 static int
-direct_renameat2 (struct ovl_layer *l, int olddirfd, const char *oldpath,
+direct_renameat2 (int olddirfd, const char *oldpath,
                   int newdirfd, const char *newpath, unsigned int flags)
 {
   return syscall (SYS_renameat2, olddirfd, oldpath, newdirfd, newpath, flags);
@@ -1097,19 +1097,13 @@
 
   new_name = strdup (name);
   if (new_name == NULL)
-    {
-      free (ret);
-      return NULL;
-    }
+    return NULL;
+
   node_set_name (ret, new_name);
 
   ret->path = strdup (path);
   if (ret->path == NULL)
-    {
-      free (new_name);
-      free (ret);
-      return NULL;
-    }
+    return NULL;
 
   ret->whiteout = 1;
   ret->ino = &dummy_ino;
@@ -1225,7 +1219,6 @@
       for (it = layer; it; it = it->next)
         {
           ssize_t s;
-          bool stat_only = false;
           cleanup_free char *val = NULL;
           cleanup_free char *origin = NULL;
           cleanup_close int fd = -1;
@@ -1275,12 +1268,6 @@
               ret->last_layer = it;
             }
 
-          if (stat_only)
-            {
-              has_origin = false;
-              goto no_fd;
-            }
-
           s = safe_read_xattr (&val, fd, PRIVILEGED_ORIGIN_XATTR, PATH_MAX);
           if (s > 0)
             {
@@ -1766,7 +1753,7 @@
           char whpath[PATH_MAX];
           const char *wh_name;
 
-          if (pnode && pnode->last_layer == it)
+          if (pnode->last_layer == it)
             stop_lookup = true;
 
           strconcat3 (path, PATH_MAX, pnode->path, "/", name);
@@ -2406,6 +2393,67 @@
   return 0;
 }
 
+static int
+empty_dirfd (int fd)
+{
+  cleanup_dir DIR *dp = NULL;
+  struct dirent *dent;
+
+  dp = fdopendir (fd);
+  if (dp == NULL)
+    {
+      close (fd);
+      return -1;
+    }
+
+  for (;;)
+    {
+      int ret;
+
+      errno = 0;
+      dent = readdir (dp);
+      if (dent == NULL)
+        {
+          if (errno)
+            return -1;
+
+          break;
+        }
+      if (strcmp (dent->d_name, ".") == 0)
+        continue;
+      if (strcmp (dent->d_name, "..") == 0)
+        continue;
+
+      ret = unlinkat (dirfd (dp), dent->d_name, 0);
+      if (ret < 0 && errno == EISDIR)
+        {
+          ret = unlinkat (dirfd (dp), dent->d_name, AT_REMOVEDIR);
+          if (ret < 0 && errno == ENOTEMPTY)
+            {
+              int dfd;
+
+              dfd = safe_openat (dirfd (dp), dent->d_name, O_DIRECTORY, 0);
+              if (dfd < 0)
+                return -1;
+
+              ret = empty_dirfd (dfd);
+              if (ret < 0)
+                return -1;
+
+              ret = unlinkat (dirfd (dp), dent->d_name, AT_REMOVEDIR);
+              if (ret < 0)
+                return -1;
+
+              continue;
+            }
+        }
+      if (ret < 0)
+        return ret;
+    }
+
+  return 0;
+}
+
 static int create_node_directory (struct ovl_data *lo, struct ovl_node *src);
 
 static int
@@ -2445,7 +2493,7 @@
   if (ret < 0)
     goto out;
 
-  ret = dfd = TEMP_FAILURE_RETRY (openat (lo->workdir_fd, wd_tmp_file_name, 
O_RDONLY));
+  ret = dfd = TEMP_FAILURE_RETRY (safe_openat (lo->workdir_fd, 
wd_tmp_file_name, O_RDONLY, 0));
   if (ret < 0)
     goto out;
 
@@ -2495,6 +2543,24 @@
   ret = renameat (lo->workdir_fd, wd_tmp_file_name, dirfd, name);
   if (ret < 0)
     {
+      if (errno == EEXIST)
+        {
+          int dfd = -1;
+
+          ret = direct_renameat2 (lo->workdir_fd, wd_tmp_file_name, dirfd, 
name, RENAME_EXCHANGE);
+          if (ret < 0)
+            goto out;
+
+          dfd = TEMP_FAILURE_RETRY (safe_openat (lo->workdir_fd, 
wd_tmp_file_name, O_DIRECTORY, 0));
+          if (dfd < 0)
+            return -1;
+
+          ret = empty_dirfd (dfd);
+          if (ret < 0)
+            goto out;
+
+          return unlinkat (lo->workdir_fd, wd_tmp_file_name, AT_REMOVEDIR);
+        }
       if (errno == ENOTDIR)
         unlinkat (dirfd, name, 0);
       if (errno == ENOENT && parent)
@@ -2570,12 +2636,14 @@
         break;
 
       written = 0;
-      {
-        ret = TEMP_FAILURE_RETRY (write (dfd, buf + written, nread));
-        if (ret < 0)
-          return ret;
-        nread -= ret;
-      }
+      do
+        {
+          ret = TEMP_FAILURE_RETRY (write (dfd, buf + written, nread));
+          if (ret < 0)
+            return ret;
+          nread -= ret;
+          written += ret;
+        }
       while (nread);
     }
   return 0;
@@ -2645,11 +2713,11 @@
       goto success;
     }
 
-  ret = sfd = node->layer->ds->openat (node->layer, node->path, 
O_RDONLY|O_NONBLOCK, 0755);
+  ret = sfd = node->layer->ds->openat (node->layer, node->path, 
O_RDONLY|O_NONBLOCK, 0);
   if (sfd < 0)
     goto exit;
 
-  ret = dfd = TEMP_FAILURE_RETRY (openat (lo->workdir_fd, wd_tmp_file_name, 
O_CREAT|O_WRONLY, st.st_mode));
+  ret = dfd = TEMP_FAILURE_RETRY (safe_openat (lo->workdir_fd, 
wd_tmp_file_name, O_CREAT|O_WRONLY, st.st_mode));
   if (dfd < 0)
     goto exit;
 
@@ -2715,7 +2783,8 @@
   if (ret < 0)
     goto exit;
 
-  if (set_fd_origin (dfd, node->path) < 0)
+  ret = set_fd_origin (dfd, node->path);
+  if (ret < 0)
     goto exit;
 
   /* Finally, move the file to its destination.  */
@@ -2827,73 +2896,12 @@
 }
 
 static int
-empty_dirfd (int fd)
-{
-  cleanup_dir DIR *dp = NULL;
-  struct dirent *dent;
-
-  dp = fdopendir (fd);
-  if (dp == NULL)
-    {
-      close (fd);
-      return -1;
-    }
-
-  for (;;)
-    {
-      int ret;
-
-      errno = 0;
-      dent = readdir (dp);
-      if (dent == NULL)
-        {
-          if (errno)
-            return -1;
-
-          break;
-        }
-      if (strcmp (dent->d_name, ".") == 0)
-        continue;
-      if (strcmp (dent->d_name, "..") == 0)
-        continue;
-
-      ret = unlinkat (dirfd (dp), dent->d_name, 0);
-      if (ret < 0 && errno == EISDIR)
-        {
-          ret = unlinkat (dirfd (dp), dent->d_name, AT_REMOVEDIR);
-          if (ret < 0 && errno == ENOTEMPTY)
-            {
-              int dfd;
-
-              dfd = openat (dirfd (dp), dent->d_name, O_DIRECTORY);
-              if (dfd < 0)
-                return -1;
-
-              ret = empty_dirfd (dfd);
-              if (ret < 0)
-                return -1;
-
-              ret = unlinkat (dirfd (dp), dent->d_name, AT_REMOVEDIR);
-              if (ret < 0)
-                return -1;
-
-              continue;
-            }
-        }
-      if (ret < 0)
-        return ret;
-    }
-
-  return 0;
-}
-
-static int
 empty_dir (struct ovl_layer *l, const char *path)
 {
   cleanup_close int cleanup_fd = -1;
   int ret;
 
-  cleanup_fd = TEMP_FAILURE_RETRY (openat (l->fd, path, O_DIRECTORY));
+  cleanup_fd = TEMP_FAILURE_RETRY (safe_openat (l->fd, path, O_DIRECTORY, 0));
   if (cleanup_fd < 0)
     return -1;
 
@@ -3171,7 +3179,7 @@
   /* try to create directly the file if it doesn't need to be chowned.  */
   if (uid == lo->uid && gid == lo->gid)
     {
-      ret = TEMP_FAILURE_RETRY (openat (get_upper_layer (lo)->fd, path, flags, 
mode));
+      ret = TEMP_FAILURE_RETRY (safe_openat (get_upper_layer (lo)->fd, path, 
flags, mode));
       if (ret >= 0)
         return ret;
       /* if it fails (e.g. there is a whiteout) then fallback to create it in
@@ -3180,7 +3188,7 @@
 
   sprintf (wd_tmp_file_name, "%lu", get_next_wd_counter ());
 
-  fd = TEMP_FAILURE_RETRY (openat (lo->workdir_fd, wd_tmp_file_name, flags, 
mode));
+  fd = TEMP_FAILURE_RETRY (safe_openat (lo->workdir_fd, wd_tmp_file_name, 
flags, mode));
   if (fd < 0)
     return -1;
   if (uid != lo->uid || gid != lo->gid)
@@ -3590,7 +3598,7 @@
       switch (mode & S_IFMT)
         {
         case S_IFREG:
-          cleaned_up_fd = fd = TEMP_FAILURE_RETRY (openat (dirfd, node->path, 
O_NOFOLLOW|O_NONBLOCK|(to_set & FUSE_SET_ATTR_SIZE ? O_WRONLY : 0)));
+          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);
@@ -3599,7 +3607,7 @@
           break;
 
         case S_IFDIR:
-          cleaned_up_fd = fd = TEMP_FAILURE_RETRY (openat (dirfd, node->path, 
O_NOFOLLOW|O_NONBLOCK));
+          cleaned_up_fd = fd = TEMP_FAILURE_RETRY (safe_openat (dirfd, 
node->path, O_NOFOLLOW|O_NONBLOCK, 0));
           if (fd < 0)
             {
               if (errno != ELOOP)
@@ -3611,7 +3619,7 @@
           break;
 
         case S_IFLNK:
-          cleaned_up_fd = TEMP_FAILURE_RETRY (openat (dirfd, node->path, 
O_PATH|O_NOFOLLOW|O_NONBLOCK));
+          cleaned_up_fd = TEMP_FAILURE_RETRY (safe_openat (dirfd, node->path, 
O_PATH|O_NOFOLLOW|O_NONBLOCK, 0));
           if (cleaned_up_fd < 0)
             {
               fuse_reply_err (req, errno);
@@ -3646,7 +3654,7 @@
       if (fd >= 0)
         ret = futimens (fd, times);
       else
-        ret = utimensat (AT_FDCWD, path, times, AT_SYMLINK_NOFOLLOW);
+        ret = utimensat (AT_FDCWD, path, times, 0);
       if (ret < 0)
         {
           fuse_reply_err (req, errno);
@@ -3981,7 +3989,7 @@
   if (pnode == NULL)
     goto error;
 
-  ret = TEMP_FAILURE_RETRY (openat (node_dirfd (pnode), pnode->path, 
O_DIRECTORY));
+  ret = TEMP_FAILURE_RETRY (safe_openat (node_dirfd (pnode), pnode->path, 
O_DIRECTORY, 0));
   if (ret < 0)
     goto error;
   srcfd = ret;
@@ -3990,7 +3998,7 @@
   if (destpnode == NULL)
     goto error;
 
-  ret = TEMP_FAILURE_RETRY (openat (node_dirfd (destpnode), destpnode->path, 
O_DIRECTORY));
+  ret = TEMP_FAILURE_RETRY (safe_openat (node_dirfd (destpnode), 
destpnode->path, O_DIRECTORY, 0));
   if (ret < 0)
     goto error;
   destfd = ret;
@@ -4016,7 +4024,7 @@
     goto error;
 
 
-  ret = direct_renameat2 (node->layer, srcfd, name, destfd, newname, flags);
+  ret = direct_renameat2 (srcfd, name, destfd, newname, flags);
   if (ret < 0)
     goto error;
 
@@ -4106,7 +4114,7 @@
   if (pnode == NULL)
     goto error;
 
-  ret = TEMP_FAILURE_RETRY (openat (node_dirfd (pnode), pnode->path, 
O_DIRECTORY));
+  ret = TEMP_FAILURE_RETRY (safe_openat (node_dirfd (pnode), pnode->path, 
O_DIRECTORY, 0));
   if (ret < 0)
     goto error;
   srcfd = ret;
@@ -4115,7 +4123,7 @@
   if (destpnode == NULL)
     goto error;
 
-  ret = TEMP_FAILURE_RETRY (openat (node_dirfd (destpnode), destpnode->path, 
O_DIRECTORY));
+  ret = TEMP_FAILURE_RETRY (safe_openat (node_dirfd (destpnode), 
destpnode->path, O_DIRECTORY, 0));
   if (ret < 0)
     goto error;
   destfd = ret;
@@ -4189,7 +4197,7 @@
    so that with one operation we get both the rename and the whiteout created. 
 */
   if (destnode_is_whiteout)
     {
-      ret = direct_renameat2 (get_upper_layer (lo), srcfd, name, destfd, 
newname, flags|RENAME_EXCHANGE);
+      ret = direct_renameat2 (srcfd, name, destfd, newname, 
flags|RENAME_EXCHANGE);
       if (ret == 0)
         goto done;
 
@@ -4209,11 +4217,11 @@
 
   /* Try to create the whiteout atomically, if it fails do the
      rename+mknod separately.  */
-  ret = direct_renameat2 (get_upper_layer (lo), srcfd, name, destfd,
+  ret = direct_renameat2 (srcfd, name, destfd,
                           newname, flags|RENAME_WHITEOUT);
   if (ret < 0)
     {
-      ret = direct_renameat2 (get_upper_layer (lo), srcfd, name, destfd,
+      ret = direct_renameat2 (srcfd, name, destfd,
                               newname, flags);
       if (ret < 0)
         goto error;
@@ -4622,7 +4630,7 @@
 
   if (fd < 0)
     {
-      cfd = openat (l->fd, path, O_NOFOLLOW|O_DIRECTORY);
+      cfd = safe_openat (l->fd, path, O_NOFOLLOW|O_DIRECTORY, 0);
       if (cfd < 0)
           return cfd;
       fd = cfd;
@@ -4707,7 +4715,7 @@
 }
 
 static void
-ovl_ioctl (fuse_req_t req, fuse_ino_t ino, unsigned int cmd, void *arg,
+ovl_ioctl (fuse_req_t req, fuse_ino_t ino, int cmd, void *arg,
            struct fuse_file_info *fi, unsigned int flags,
            const void *in_buf, size_t in_bufsz, size_t out_bufsz)
 {
@@ -4813,7 +4821,7 @@
     }
 
   dirfd = node_dirfd (node);
-  fd = openat (dirfd, node->path, O_NONBLOCK|O_NOFOLLOW|O_WRONLY, 0755);
+  fd = safe_openat (dirfd, node->path, O_NONBLOCK|O_NOFOLLOW|O_WRONLY, 0);
   if (fd < 0)
     {
       fuse_reply_err (req, errno);
@@ -4878,7 +4886,7 @@
       return;
     }
 
-  fd_dest = TEMP_FAILURE_RETRY (openat (node_dirfd (dnode), dnode->path, 
O_NONBLOCK|O_NOFOLLOW|O_WRONLY));
+  fd_dest = TEMP_FAILURE_RETRY (safe_openat (node_dirfd (dnode), dnode->path, 
O_NONBLOCK|O_NOFOLLOW|O_WRONLY, 0));
   if (fd_dest < 0)
     {
       fuse_reply_err (req, errno);
@@ -4993,6 +5001,8 @@
     return 1;
   if (strcmp (arg, "max_write") == 0)
     return 1;
+  if (strcmp (arg, "ro") == 0)
+    return 1;
 
   if (key == FUSE_OPT_KEY_NONOPT)
     {
@@ -5013,7 +5023,12 @@
 get_new_args (int *argc, char **argv)
 {
   int i;
-  char **newargv = malloc (sizeof (char *) * (*argc + 2));
+  char **newargv;
+
+  newargv = malloc (sizeof (char *) * (*argc + 2));
+  if (newargv == NULL)
+    error (EXIT_FAILURE, 0, "error allocating memory");
+
   newargv[0] = argv[0];
   if (geteuid() == 0)
     newargv[1] = "-odefault_permissions,allow_other,suid,noatime,lazytime";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.0.0/tests/fedora-installs.sh 
new/fuse-overlayfs-1.1.0/tests/fedora-installs.sh
--- old/fuse-overlayfs-1.0.0/tests/fedora-installs.sh   2020-04-17 
11:10:44.000000000 +0200
+++ new/fuse-overlayfs-1.1.0/tests/fedora-installs.sh   2020-06-18 
09:15:04.000000000 +0200
@@ -169,3 +169,22 @@
 rm -rf merged/a/3
 
 test $(stat -c %h merged/a) = 4
+
+# symlink mtime
+
+touch merged/afile
+ln -s afile merged/alink
+touch -h -d "2020-01-02 12:13:14" merged/alink
+stat --format "%y" merged/alink | grep "12:13:14"
+stat --format "%x" merged/alink | grep "12:13:14"
+
+# file mtime
+touch -h -d "2020-01-02 11:12:13" merged/afile
+stat --format "%y" merged/afile | grep "11:12:13"
+stat --format "%x" merged/afile | grep "11:12:13"
+
+# dir mtime
+mkdir merged/adir
+touch -h -d "2020-01-02 10:11:12" merged/adir
+stat --format "%y" merged/adir | grep "10:11:12"
+stat --format "%x" merged/adir | grep "10:11:12"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.0.0/tests/unlink.sh 
new/fuse-overlayfs-1.1.0/tests/unlink.sh
--- old/fuse-overlayfs-1.0.0/tests/unlink.sh    2020-04-17 11:10:44.000000000 
+0200
+++ new/fuse-overlayfs-1.1.0/tests/unlink.sh    2020-06-18 09:15:04.000000000 
+0200
@@ -1,5 +1,7 @@
 #!/bin/sh
 
+rm -rf lower upper workdir merged
+
 mkdir lower upper workdir merged
 
 touch lower/a
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.0.0/utils.c 
new/fuse-overlayfs-1.1.0/utils.c
--- old/fuse-overlayfs-1.0.0/utils.c    2020-04-17 11:10:44.000000000 +0200
+++ new/fuse-overlayfs-1.1.0/utils.c    2020-06-18 09:15:04.000000000 +0200
@@ -25,6 +25,10 @@
 #include <fcntl.h>
 #include <string.h>
 #include <sys/sysmacros.h>
+#include <sys/syscall.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 
 #ifndef TEMP_FAILURE_RETRY
 #define TEMP_FAILURE_RETRY(expression) \
@@ -35,6 +39,62 @@
        __result; }))
 #endif
 
+#ifndef RESOLVE_IN_ROOT
+# define RESOLVE_IN_ROOT               0x10
+#endif
+#ifndef __NR_openat2
+# define __NR_openat2 437
+#endif
+
+/* List of all valid flags for the open/openat flags argument: */
+#define VALID_OPEN_FLAGS \
+  (O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC | \
+   O_APPEND | O_NDELAY | O_NONBLOCK | O_NDELAY | O_SYNC | O_DSYNC |     \
+   FASYNC | O_DIRECT | O_LARGEFILE | O_DIRECTORY | O_NOFOLLOW |         \
+   O_NOATIME | O_CLOEXEC | O_PATH | O_TMPFILE)
+
+static int
+syscall_openat2 (int dirfd, const char *path, uint64_t flags, uint64_t mode, 
uint64_t resolve)
+{
+  struct openat2_open_how
+    {
+      uint64_t flags;
+      uint64_t mode;
+      uint64_t resolve;
+    }
+  how =
+    {
+     .flags = flags & VALID_OPEN_FLAGS,
+     .mode = (flags & O_CREAT) ? (mode & 07777) : 0,
+     .resolve = resolve,
+    };
+
+  return (int) syscall (__NR_openat2, dirfd, path, &how, sizeof (how), 0);
+}
+
+int
+safe_openat (int dirfd, const char *pathname, int flags, mode_t mode)
+{
+  static bool openat2_supported = true;
+
+  if (openat2_supported)
+    {
+      int ret;
+
+      ret = syscall_openat2 (dirfd, pathname, flags, mode, RESOLVE_IN_ROOT);
+      if (ret < 0)
+        {
+          if (errno == ENOSYS)
+            openat2_supported = false;
+          if (errno == ENOSYS || errno == EINVAL)
+            goto fallback;
+        }
+      return ret;
+    }
+ fallback:
+  return openat (dirfd, pathname, flags, mode);
+}
+
 int
 file_exists_at (int dirfd, const char *pathname)
 {
@@ -148,7 +208,7 @@
 {
   out[0] = '\0';
 
-  *fd = l->ds->openat (l, path, O_NONBLOCK|O_NOFOLLOW|flags, 0755);
+  *fd = l->ds->openat (l, path, O_NONBLOCK|O_NOFOLLOW|flags, 0);
   if (*fd < 0 && (errno == ELOOP || errno == EISDIR || errno == ENXIO))
     {
       strconcat3 (out, PATH_MAX, l->path, "/", path);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fuse-overlayfs-1.0.0/utils.h 
new/fuse-overlayfs-1.1.0/utils.h
--- old/fuse-overlayfs-1.0.0/utils.h    2020-04-17 11:10:44.000000000 +0200
+++ new/fuse-overlayfs-1.1.0/utils.h    2020-06-18 09:15:04.000000000 +0200
@@ -53,4 +53,6 @@
 void statx_to_stat (struct statx *stx, struct stat *st);
 # endif
 
+int safe_openat (int dirfd, const char *pathname, int flags, mode_t mode);
+
 #endif


Reply via email to