Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package tar for openSUSE:Factory checked in 
at 2022-11-02 12:46:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/tar (Old)
 and      /work/SRC/openSUSE:Factory/.tar.new.2275 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "tar"

Wed Nov  2 12:46:18 2022 rev:78 rq:1032467 version:1.34

Changes:
--------
--- /work/SRC/openSUSE:Factory/tar/tar.changes  2022-08-25 15:08:48.477178826 
+0200
+++ /work/SRC/openSUSE:Factory/.tar.new.2275/tar.changes        2022-11-02 
12:46:20.553324689 +0100
@@ -1,0 +2,10 @@
+Thu Oct 27 13:55:03 UTC 2022 - Danilo Spinella <danilo.spine...@suse.com>
+
+- Fix unexpected inconsistency when making directory, bsc#1203600
+  * tar-avoid-overflow-in-symlinks-tests.patch
+  * tar-fix-extract-unlink.patch
+- Update race condition fix, bsc#1200657
+  * tar-fix-race-condition.patch
+- Refresh bsc1200657.patch
+
+-------------------------------------------------------------------

New:
----
  tar-avoid-overflow-in-symlinks-tests.patch
  tar-fix-extract-unlink.patch
  tar-fix-race-condition.patch

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

Other differences:
------------------
++++++ tar.spec ++++++
--- /var/tmp/diff_new_pack.zNMgEt/_old  2022-11-02 12:46:24.817346334 +0100
+++ /var/tmp/diff_new_pack.zNMgEt/_new  2022-11-02 12:46:24.833346415 +0100
@@ -39,9 +39,14 @@
 Patch5:         add_readme-tests.patch
 Patch6:         tar-PIE.patch
 Patch7:         tests-skip-time01-on-32bit-time_t.patch
-# PATCH-FIX-OPENSUSE danilo.spine...@suse.com bsc#1200657
+# PATCH-FIX-UPSTREAM danilo.spine...@suse.com bsc#1200657
 # fix race condition while creating intermediate subdirectories
-Patch8:         bsc1200657.patch
+Patch8:         tar-fix-race-condition.patch
+# PATCH-FIX-UPSTREAM danilo.spine...@suse.com bsc#1203600
+# Unexpected inconsistency when making directory
+Patch9:         tar-avoid-overflow-in-symlinks-tests.patch
+Patch10:        bsc1200657.patch
+Patch11:        tar-fix-extract-unlink.patch
 BuildRequires:  automake >= 1.15
 BuildRequires:  libacl-devel
 BuildRequires:  libselinux-devel
@@ -113,6 +118,9 @@
 %patch6 -p1
 %patch7 -p1
 %patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
 
 %build
 %define my_cflags -W -Wall -Wpointer-arith -Wstrict-prototypes 
-Wformat-security -Wno-unused-parameter -fPIE

++++++ bsc1200657.patch ++++++
--- /var/tmp/diff_new_pack.zNMgEt/_old  2022-11-02 12:46:24.901346760 +0100
+++ /var/tmp/diff_new_pack.zNMgEt/_new  2022-11-02 12:46:24.917346841 +0100
@@ -1,139 +1,58 @@
-From 49b9f54ff66d126c4c0d58ccfbc2b85f96f845fc Mon Sep 17 00:00:00 2001
-From: Paul Eggert <egg...@cs.ucla.edu>
-Date: Thu, 31 Mar 2022 18:26:03 -0700
-Subject: [PATCH] Retry file creation more aggressively
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
+From 79d1ac38c19faad64f0e993180bf1ad27f217072 Mon Sep 17 00:00:00 2001
+From: James Abbatiello <abb...@gmail.com>
+Date: Fri, 10 Jun 2022 18:25:13 -0700
+Subject: tar: fix race condition
 
-* src/extract.c (maybe_recoverable): When deciding whether to
-retry file creation, don???t insist on our making intermediate
-subdirectories; it???s OK if some other process made them.
-Problem reported by James Abbatiello in:
+Problem reported in:
 https://lists.gnu.org/r/bug-tar/2022-03/msg00000.html
+* src/extract.c (make_directories): Retry the file creation as
+long as the directory exists, regardless of whether tar itself
+created the directory.
+Copyright-paperwork-exempt: Yes
 ---
- src/extract.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
+ src/extract.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
 
-Index: tar-1.34/src/extract.c
-===================================================================
---- tar-1.34.orig/src/extract.c
-+++ tar-1.34/src/extract.c
-@@ -645,9 +645,9 @@ fixup_delayed_set_stat (char const *src,
-    it's because some required directory was not present, and if so,
+diff --git a/src/extract.c b/src/extract.c
+index 0753dec..fda4617 100644
+--- a/src/extract.c
++++ b/src/extract.c
+@@ -638,10 +638,9 @@ fixup_delayed_set_stat (char const *src, char const *dst)
+ 
+ /* After a file/link/directory creation has failed due to ENOENT,
     create all required directories.  Return zero if all the required
-    directories were created, nonzero (issuing a diagnostic) otherwise.
+-   directories were created, nonzero (issuing a diagnostic) otherwise.
 -   Set *INTERDIR_MADE if at least one directory was created.  */
-+   */
++   directories were created, nonzero (issuing a diagnostic) otherwise.  */
  static int
 -make_directories (char *file_name, bool *interdir_made)
 +make_directories (char *file_name)
  {
    char *cursor0 = file_name + FILE_SYSTEM_PREFIX_LEN (file_name);
    char *cursor;                       /* points into the file name */
-@@ -689,7 +689,6 @@ make_directories (char *file_name, bool
+@@ -685,7 +684,6 @@ make_directories (char *file_name, bool *interdir_made)
                          desired_mode, AT_SYMLINK_NOFOLLOW);
  
          print_for_mkdir (file_name, cursor - file_name, desired_mode);
 -        *interdir_made = true;
+         parent_end = NULL;
        }
-       else if (errno == EEXIST)
-       status = 0;
-@@ -829,8 +828,11 @@ maybe_recoverable (char *file_name, bool
+       else
+@@ -841,8 +839,11 @@ maybe_recoverable (char *file_name, bool regular, bool 
*interdir_made)
  
      case ENOENT:
        /* Attempt creating missing intermediate directories.  */
--      if (make_directories (file_name, interdir_made) == 0 && *interdir_made)
+-      if (make_directories (file_name, interdir_made) == 0)
 -      return RECOVER_OK;
 +      if (make_directories (file_name) == 0)
-+             {
-+               *interdir_made = true;
-+               return RECOVER_OK;
-+             }
++      {
++        *interdir_made = true;
++        return RECOVER_OK;
++      }
        break;
  
      default:
-@@ -1329,7 +1331,7 @@ extract_file (char *file_name, int typef
-    first. If it doesn't exist, there is no matching entry in the list.
-    Otherwise, look for the entry in list which has the matching dev
-    and ino numbers.
--   
-+
-    This approach avoids scanning the singly-linked list in obvious cases
-    and does not rely on comparing file names, which may differ for
-    various reasons (e.g. relative vs. absolute file names).
-@@ -1342,14 +1344,14 @@ find_delayed_link_source (char const *na
- 
-   if (!delayed_link_head)
-     return NULL;
--  
-+
-   if (fstatat (chdir_fd, name, &st, AT_SYMLINK_NOFOLLOW))
-     {
-       if (errno != ENOENT)
-       stat_error (name);
-       return NULL;
-     }
--  
-+
-   for (dl = delayed_link_head; dl; dl = dl->next)
-     {
-       if (dl->dev == st.st_dev && dl->ino == st.st_ino)
-@@ -1357,7 +1359,7 @@ find_delayed_link_source (char const *na
-     }
-   return dl;
- }
--  
-+
- /* Create a placeholder file with name FILE_NAME, which will be
-    replaced after other extraction is done by a symbolic link if
-    IS_SYMLINK is true, and by a hard link otherwise.  Set
-@@ -1385,7 +1387,7 @@ create_placeholder_file (char *file_name
-          */
-         return 0;
-       }
--      
-+
-       switch (maybe_recoverable (file_name, false, interdir_made))
-       {
-       case RECOVER_OK:
-@@ -1467,7 +1469,7 @@ extract_link (char *file_name, int typef
-   char const *link_name;
-   int rc;
-   struct delayed_link *dl;
--  
-+
-   link_name = current_stat_info.link_name;
- 
-   if (! absolute_names_option && contains_dot_dot (link_name))
-@@ -1475,7 +1477,7 @@ extract_link (char *file_name, int typef
-   dl = find_delayed_link_source (link_name);
-   if (dl)
-     return create_placeholder_file (file_name, false, &interdir_made, dl);
--  
-+
-   do
-     {
-       struct stat st1, st2;
-@@ -1697,7 +1699,7 @@ prepare_to_extract (char const *file_nam
- 
-     case GNUTYPE_VOLHDR:
-       return false;
--      
-+
-     case GNUTYPE_MULTIVOL:
-       ERROR ((0, 0,
-             _("%s: Cannot extract -- file is continued from another volume"),
-@@ -1753,7 +1755,7 @@ prepare_to_extract (char const *file_nam
-       }
-     }
-   *fun = extractor;
--  
-+
-   return true;
- }
- 
-@@ -1934,12 +1936,11 @@ rename_directory (char *src, char *dst)
+@@ -1944,12 +1945,11 @@ rename_directory (char *src, char *dst)
    else
      {
        int e = errno;
@@ -147,4 +66,7 @@
            {
              if (renameat (chdir_fd, src, chdir_fd, dst) == 0)
                return true;
+-- 
+cgit v1.1
+
 


++++++ tar-avoid-overflow-in-symlinks-tests.patch ++++++
>From d935dc7d1c150b3425dd43dc13a4dd2e2b712c26 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Mon, 13 Jun 2022 17:02:54 -0700
Subject: Avoid EOVERFLOW problems in some symlink tests

* src/extract.c (is_directory_link): New arg ST.  Caller changed.
(is_directory_link, open_output_file):
Use readlinkat, not fstatat, to determine whether a string
names a symlink.  This avoids EOVERFLOW issues.
(extract_dir): Avoid duplicate calls to fstatat when
keep_directory_symlink_option && fstatat_flags == 0
and the file is a symlink to an existing file.
---
 src/extract.c | 28 ++++++++++++----------------
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/src/extract.c b/src/extract.c
index fda4617..6d2543f 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -982,18 +982,12 @@ apply_nonancestor_delayed_set_stat (char const 
*file_name, bool after_links)
 
 
 static bool
-is_directory_link (const char *file_name)
+is_directory_link (char const *file_name, struct stat *st)
 {
-  struct stat st;
-  int e = errno;
-  int res;
-
-  res = (fstatat (chdir_fd, file_name, &st, AT_SYMLINK_NOFOLLOW) == 0 &&
-        S_ISLNK (st.st_mode) &&
-        fstatat (chdir_fd, file_name, &st, 0) == 0 &&
-        S_ISDIR (st.st_mode));
-  errno = e;
-  return res;
+  char buf[1];
+  return (0 <= readlinkat (chdir_fd, file_name, buf, sizeof buf)
+         && fstatat (chdir_fd, file_name, st, 0) == 0
+         && S_ISDIR (st->st_mode));
 }
 
 /* Given struct stat of a directory (or directory member) whose ownership
@@ -1066,11 +1060,14 @@ extract_dir (char *file_name, int typeflag)
              || old_files_option == OVERWRITE_OLD_FILES))
        {
          struct stat st;
+         st.st_mode = 0;
 
-         if (keep_directory_symlink_option && is_directory_link (file_name))
+         if (keep_directory_symlink_option
+             && is_directory_link (file_name, &st))
            return 0;
 
-         if (deref_stat (file_name, &st) == 0)
+         if ((st.st_mode != 0 && fstatat_flags == 0)
+             || deref_stat (file_name, &st) == 0)
            {
              current_mode = st.st_mode;
              current_mode_mask = ALL_MODE_BITS;
@@ -1178,9 +1175,8 @@ open_output_file (char const *file_name, int typeflag, 
mode_t mode,
   if (! HAVE_WORKING_O_NOFOLLOW
       && overwriting_old_files && ! dereference_option)
     {
-      struct stat st;
-      if (fstatat (chdir_fd, file_name, &st, AT_SYMLINK_NOFOLLOW) == 0
-         && S_ISLNK (st.st_mode))
+      char buf[1];
+      if (0 <= readlinkat (chdir_fd, file_name, buf, sizeof buf))
        {
          errno = ELOOP;
          return -1;
-- 
cgit v1.1


++++++ tar-fix-extract-unlink.patch ++++++
>From 17debecd7300e94f590b8ce167a8c0735cb6d57d Mon Sep 17 00:00:00 2001
From: Sergey Poznyakoff <g...@gnu.org>
Date: Sat, 22 Oct 2022 12:06:45 +0300
Subject: Fix savannah bug #63123

The bug was introduced by commit 79d1ac38c1, which didn't take into
account all the consequences of returning RECOVER_OK on EEXIST, in
particular interactions with the delayed_set_stat logic.

The commit 79d1ac38c1 is reverted (the bug it was intended to fix
was actually fixed by 79a442d7b0).  Instead:

* src/extract.c (maybe_recoverable): Don't call maybe_recoverable
if EEXIST is reported when UNLINK_FIRST_OLD_FILES option is set.
---
 src/extract.c | 108 +++++++++++++++++++++++++++++++---------------------------
 1 file changed, 58 insertions(+), 50 deletions(-)

diff --git a/src/extract.c b/src/extract.c
index 78de47f..37ab295 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -679,9 +679,10 @@ fixup_delayed_set_stat (char const *src, char const *dst)
 
 /* After a file/link/directory creation has failed due to ENOENT,
    create all required directories.  Return zero if all the required
-   directories were created, nonzero (issuing a diagnostic) otherwise.  */
+   directories were created, nonzero (issuing a diagnostic) otherwise.
+   Set *INTERDIR_MADE if at least one directory was created.  */
 static int
-make_directories (char *file_name)
+make_directories (char *file_name, bool *interdir_made)
 {
   char *cursor0 = file_name + FILE_SYSTEM_PREFIX_LEN (file_name);
   char *cursor;                        /* points into the file name */
@@ -725,6 +726,7 @@ make_directories (char *file_name)
                          desired_mode, AT_SYMLINK_NOFOLLOW);
 
          print_for_mkdir (file_name, cursor - file_name, desired_mode);
+         *interdir_made = true;
          parent_end = NULL;
        }
       else
@@ -879,12 +881,9 @@ maybe_recoverable (char *file_name, bool regular, bool 
*interdir_made)
       FALLTHROUGH;
 
     case ENOENT:
-      /* Attempt creating missing intermediate directories.  */
-      if (make_directories (file_name) == 0)
-       {
-         *interdir_made = true;
-         return RECOVER_OK;
-       }
+      /* Attempt creating missing intermediate directories. */
+      if (make_directories (file_name, interdir_made) == 0)
+       return RECOVER_OK;
       break;
 
     default:
@@ -1072,61 +1071,69 @@ extract_dir (char *file_name, int typeflag)
          break;
        }
 
-      if (errno == EEXIST
-         && (interdir_made
+      if (errno == EEXIST)
+       {
+         if (interdir_made
              || keep_directory_symlink_option
              || old_files_option == NO_OVERWRITE_DIR_OLD_FILES
              || old_files_option == DEFAULT_OLD_FILES
-             || old_files_option == OVERWRITE_OLD_FILES))
-       {
-         struct stat st;
-         st.st_mode = 0;
-
-         if (keep_directory_symlink_option
-             && is_directory_link (file_name, &st))
-           return 0;
-
-         if ((st.st_mode != 0 && fstatat_flags == 0)
-             || deref_stat (file_name, &st) == 0)
+             || old_files_option == OVERWRITE_OLD_FILES)
            {
-             current_mode = st.st_mode;
-             current_mode_mask = ALL_MODE_BITS;
+             struct stat st;
+             st.st_mode = 0;
+
+             if (keep_directory_symlink_option
+                 && is_directory_link (file_name, &st))
+               return 0;
 
-             if (S_ISDIR (current_mode))
+             if ((st.st_mode != 0 && fstatat_flags == 0)
+                 || deref_stat (file_name, &st) == 0)
                {
-                 if (interdir_made)
-                   {
-                     repair_delayed_set_stat (file_name, &st);
-                     return 0;
-                   }
-                 else if (old_files_option == NO_OVERWRITE_DIR_OLD_FILES)
+                 current_mode = st.st_mode;
+                 current_mode_mask = ALL_MODE_BITS;
+
+                 if (S_ISDIR (current_mode))
                    {
-                     /* Temporarily change the directory mode to a safe
-                        value, to be able to create files in it, should
-                        the need be.
-                     */
-                     mode = safe_dir_mode (&st);
-                     status = fd_chmod(-1, file_name, mode,
-                                       AT_SYMLINK_NOFOLLOW, DIRTYPE);
-                     if (status == 0)
+                     if (interdir_made)
                        {
-                         /* Store the actual directory mode, to be restored
-                            later.
-                         */
-                         current_stat_info.stat = st;
-                         current_mode = mode & ~ current_umask;
-                         current_mode_mask = MODE_RWX;
-                         atflag = AT_SYMLINK_NOFOLLOW;
-                         break;
+                         repair_delayed_set_stat (file_name, &st);
+                         return 0;
                        }
-                     else
+                     else if (old_files_option == NO_OVERWRITE_DIR_OLD_FILES)
                        {
-                         chmod_error_details (file_name, mode);
+                         /* Temporarily change the directory mode to a safe
+                            value, to be able to create files in it, should
+                            the need be.
+                         */
+                         mode = safe_dir_mode (&st);
+                         status = fd_chmod (-1, file_name, mode,
+                                            AT_SYMLINK_NOFOLLOW, DIRTYPE);
+                         if (status == 0)
+                           {
+                             /* Store the actual directory mode, to be restored
+                                later.
+                             */
+                             current_stat_info.stat = st;
+                             current_mode = mode & ~ current_umask;
+                             current_mode_mask = MODE_RWX;
+                             atflag = AT_SYMLINK_NOFOLLOW;
+                             break;
+                           }
+                         else
+                           {
+                             chmod_error_details (file_name, mode);
+                           }
                        }
+                     break;
                    }
-                 break;
                }
            }
+         else if (old_files_option == UNLINK_FIRST_OLD_FILES)
+           {
+             status = 0;
+             break;
+           }
+         
          errno = EEXIST;
        }
 
@@ -1978,11 +1985,12 @@ rename_directory (char *src, char *dst)
   else
     {
       int e = errno;
+      bool interdir_made;
 
       switch (e)
        {
        case ENOENT:
-         if (make_directories (dst) == 0)
+         if (make_directories (dst, &interdir_made) == 0)
            {
              if (renameat (chdir_fd, src, chdir_fd, dst) == 0)
                return true;
-- 
cgit v1.1


++++++ tar-fix-race-condition.patch ++++++
>From 79a442d7b0e92622794bfa41dee18a28e450a0dc Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Thu, 9 Jun 2022 22:09:34 -0700
Subject: tar: fix race condition

Problem reported by James Abbatiello in:
https://lists.gnu.org/r/bug-tar/2022-03/msg00000.html
* src/extract.c (make_directories): Do not assume that when
mkdirat fails with errno == EEXIST that there is an existing file
that can be statted.  It could be a dangling symlink.  Instead,
wait until the end and stat it.
---
 src/extract.c | 61 ++++++++++++++++++++++++++++++++++++++---------------------
 2 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/src/extract.c b/src/extract.c
index e7be463..0753dec 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -636,8 +636,7 @@ fixup_delayed_set_stat (char const *src, char const *dst)
     }
 }
 
-/* After a file/link/directory creation has failed, see if
-   it's because some required directory was not present, and if so,
+/* After a file/link/directory creation has failed due to ENOENT,
    create all required directories.  Return zero if all the required
    directories were created, nonzero (issuing a diagnostic) otherwise.
    Set *INTERDIR_MADE if at least one directory was created.  */
@@ -646,6 +645,8 @@ make_directories (char *file_name, bool *interdir_made)
 {
   char *cursor0 = file_name + FILE_SYSTEM_PREFIX_LEN (file_name);
   char *cursor;                        /* points into the file name */
+  char *parent_end = NULL;
+  int parent_errno;
 
   for (cursor = cursor0; *cursor; cursor++)
     {
@@ -685,31 +686,47 @@ make_directories (char *file_name, bool *interdir_made)
 
          print_for_mkdir (file_name, cursor - file_name, desired_mode);
          *interdir_made = true;
+         parent_end = NULL;
        }
-      else if (errno == EEXIST)
-       status = 0;
       else
-       {
-         /* Check whether the desired file exists.  Even when the
-            file exists, mkdir can fail with some errno value E other
-            than EEXIST, so long as E describes an error condition
-            that also applies.  */
-         int e = errno;
-         struct stat st;
-         status = fstatat (chdir_fd, file_name, &st, 0);
-         if (status)
-           {
-             errno = e;
-             mkdir_error (file_name);
-           }
-       }
+       switch (errno)
+         {
+         case ELOOP: case ENAMETOOLONG: case ENOENT: case ENOTDIR:
+           /* FILE_NAME doesn't exist and couldn't be created; fail now.  */
+           mkdir_error (file_name);
+           *cursor = '/';
+           return status;
+
+         default:
+           /* FILE_NAME may be an existing directory so do not fail now.
+              Instead, arrange to check at loop exit, assuming this is
+              the last loop iteration.  */
+           parent_end = cursor;
+           parent_errno = errno;
+           break;
+         }
 
       *cursor = '/';
-      if (status)
-       return status;
     }
 
-  return 0;
+  if (!parent_end)
+    return 0;
+
+  /* Although we did not create the parent directory, some other
+     process may have created it, so check whether it exists now.  */
+  *parent_end = '\0';
+  struct stat st;
+  int stat_status = fstatat (chdir_fd, file_name, &st, 0);
+  if (!stat_status && !S_ISDIR (st.st_mode))
+    stat_status = -1;
+  if (stat_status)
+    {
+      errno = parent_errno;
+      mkdir_error (file_name);
+    }
+  *parent_end = '/';
+
+  return stat_status;
 }
 
 /* Return true if FILE_NAME (with status *STP, if STP) is not a
@@ -824,7 +841,7 @@ maybe_recoverable (char *file_name, bool regular, bool 
*interdir_made)
 
     case ENOENT:
       /* Attempt creating missing intermediate directories.  */
-      if (make_directories (file_name, interdir_made) == 0 && *interdir_made)
+      if (make_directories (file_name, interdir_made) == 0)
        return RECOVER_OK;
       break;
 
-- 
cgit v1.1

Reply via email to